【问题标题】:Preventing rigidbody jitter when MovePosition coroutine ends在 MovePosition 协程结束时防止刚体抖动
【发布时间】:2020-02-25 01:54:11
【问题描述】:

我正在制作一个系统,最好将其描述为心灵感应。玩家单击以拾取最近的可移动刚体,然后该刚体会倾斜到锚点变换(它在正弦波上上下摆动,因此看起来刚体上下浮动)。这部分工作正常。然而,当我再次左键单击时,刚体只是简单地放置到位。问题是,它会做出这种奇怪的抖动,就好像它无法决定是跟随锚还是掉到地上一样。

我的代码看起来有点像这样。

首先,检查输入是否正确:

            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.");
        }
    }

在 FixedUpdate 中检查 startCo,如果启用,则调用以下协程:

    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;
    }

锚点的正弦波/位置变化变换由空游戏对象上的单独脚本处理:

    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.

如您所见,球体似乎试图同时下落并跟随目标。当我在运行攻击功能时缓慢旋转时,球会从它应该下降的位置滑到该点和锚点结束位置之间的中间位置。

我怎样才能避免这个问题,同时仍然使这个问题相当流畅?

【问题讨论】:

  • 你自己的视频非常紧张,很难理解你的意思^^ 一般来说:不要不要Rigidbody移动到Update,而是总是在物理引擎使用的 FixedUpdate 中。对于协程,专门针对这种东西yield return new WaitForFixedUpdate()

标签: c# unity3d rigid-bodies


【解决方案1】:

这从来没有真正引起任何关注,但为了其他可能遇到此问题的人:

This link 提到使用 1 - Mathf.Exp(-20 * Time.deltaTime) 而不是常规的 Time.deltaTime - 非常适合我。

为了记录,FixedUpdate() 中的问题是相同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    相关资源
    最近更新 更多