MovePosition协程结束时防止刚体抖动
Preventing rigidbody jitter when MovePosition coroutine ends
我正在制作一个系统,这个系统可能最适合描述为心灵遥控。玩家点击以拾起最近的可移动刚体,然后它会变成一个锚点变换(它在正弦波上上下摆动,所以看起来刚体上下浮动)。这部分工作正常。然而,当我再次左键单击时,刚体将简单地放置到位。问题是,它会做这种奇怪的抖动,就好像它无法决定是应该跟随锚点还是应该掉到地上。
我的代码看起来有点像这样。
首先,检查输入是否正确:
if (holding == false && keyDown == false && abilitySwitch.disabling == false)
{
//Right click picks up the closest dragable.
if (Input.GetMouseButtonDown(1))
{
PickupClose();
}
...
else if (holding == true && keyDown == true && abilitySwitch.disabling == false)
{
//Right click while holding executes an indirect attack.
if (Input.GetMouseButtonDown(1))
{
AttackIndirect();
}
拾取函数如下所示:
public void PickupClose()
{
dragTarget = ClosestDragable();
if (ClosestDragable() != null)
{
Debug.Log("Pickup close has run.");
Debug.Log(dragTarget);
holding = true;
keyDown = true;
dragTarget.GetComponent<Rigidbody>().useGravity = false;
startCo = true;
}
else
{
Debug.Log("No dragable object in range.");
}
}
startCo在FixedUpdate中勾选,如果开启,则调用如下协程:
private IEnumerator MoveTargetToPosition(Vector3 target)
{
float t = 0f;
Vector3 start = dragTarget.transform.position;
while (t <= 1)
{
t += Time.fixedDeltaTime / baseSpeed;
dragTarget.GetComponent<Rigidbody>().MovePosition(Vector3.Slerp(start, target, t));
yield return null;
}
}
当攻击函数为运行时:
public void AttackIndirect()
{
Debug.Log("Attack indirectly has run.");
holding = false;
keyDown = false;
isHeld = false;
startCo = false;
dragTarget.GetComponent<Rigidbody>().useGravity = true;
dragTarget.GetComponent<Rigidbody>().velocity = Vector3.zero;
}
锚的正弦波 wave/position 变换由空游戏对象上的单独脚本处理:
void Update()
{
Vector3 pos = bobber.transform.position;
float newY = (Mathf.Sin(Time.time * speed)/4);
transform.position = new Vector3(pos.x, newY + 2, pos.z);
}
Here's a video of what the problem looks like.
如你所见,球体似乎在试图落下并同时跟随目标。当我在 运行 攻击函数中缓慢旋转时,球会从它应该下降的位置滑到该点和锚点结束位置之间的大约一半位置。
我怎样才能避免这个问题,同时仍然让它变得合理流畅?
这从来没有真正引起任何关注,但为了其他可能遇到此问题的人:
This link 提到使用 1 - Mathf.Exp(-20 * Time.deltaTime)
而不是常规 Time.deltaTime
- 非常适合我。
郑重声明,FixedUpdate()
中的问题相同。
我正在制作一个系统,这个系统可能最适合描述为心灵遥控。玩家点击以拾起最近的可移动刚体,然后它会变成一个锚点变换(它在正弦波上上下摆动,所以看起来刚体上下浮动)。这部分工作正常。然而,当我再次左键单击时,刚体将简单地放置到位。问题是,它会做这种奇怪的抖动,就好像它无法决定是应该跟随锚点还是应该掉到地上。
我的代码看起来有点像这样。
首先,检查输入是否正确:
if (holding == false && keyDown == false && abilitySwitch.disabling == false)
{
//Right click picks up the closest dragable.
if (Input.GetMouseButtonDown(1))
{
PickupClose();
}
...
else if (holding == true && keyDown == true && abilitySwitch.disabling == false)
{
//Right click while holding executes an indirect attack.
if (Input.GetMouseButtonDown(1))
{
AttackIndirect();
}
拾取函数如下所示:
public void PickupClose()
{
dragTarget = ClosestDragable();
if (ClosestDragable() != null)
{
Debug.Log("Pickup close has run.");
Debug.Log(dragTarget);
holding = true;
keyDown = true;
dragTarget.GetComponent<Rigidbody>().useGravity = false;
startCo = true;
}
else
{
Debug.Log("No dragable object in range.");
}
}
startCo在FixedUpdate中勾选,如果开启,则调用如下协程:
private IEnumerator MoveTargetToPosition(Vector3 target)
{
float t = 0f;
Vector3 start = dragTarget.transform.position;
while (t <= 1)
{
t += Time.fixedDeltaTime / baseSpeed;
dragTarget.GetComponent<Rigidbody>().MovePosition(Vector3.Slerp(start, target, t));
yield return null;
}
}
当攻击函数为运行时:
public void AttackIndirect()
{
Debug.Log("Attack indirectly has run.");
holding = false;
keyDown = false;
isHeld = false;
startCo = false;
dragTarget.GetComponent<Rigidbody>().useGravity = true;
dragTarget.GetComponent<Rigidbody>().velocity = Vector3.zero;
}
锚的正弦波 wave/position 变换由空游戏对象上的单独脚本处理:
void Update()
{
Vector3 pos = bobber.transform.position;
float newY = (Mathf.Sin(Time.time * speed)/4);
transform.position = new Vector3(pos.x, newY + 2, pos.z);
}
Here's a video of what the problem looks like.
如你所见,球体似乎在试图落下并同时跟随目标。当我在 运行 攻击函数中缓慢旋转时,球会从它应该下降的位置滑到该点和锚点结束位置之间的大约一半位置。
我怎样才能避免这个问题,同时仍然让它变得合理流畅?
这从来没有真正引起任何关注,但为了其他可能遇到此问题的人:
This link 提到使用 1 - Mathf.Exp(-20 * Time.deltaTime)
而不是常规 Time.deltaTime
- 非常适合我。
郑重声明,FixedUpdate()
中的问题相同。