繁体   English   中英

刚体运动时刚体速度有时为零

[英]Rigidbody velocity is zero sometimes while the rigidbody is moving

我正在尝试为我的可推送对象添加声音,并且只有一个简单的 if 语句来检查可推送对象是否正在移动。 这个概念很简单,如果物体在移动,声音应该播放,当它不移动时就不应该播放。 然而,问题是,当我调试该值时,每 5 帧左右就有一个 0。 这会导致声音的工作不一致。 我的脚本非常简单,我尝试更改为fixedupdate,但是没有用。 我在某处读到物理计算是在 fixedUpdate 中完成的。

public class PushableObject : MonoBehaviour
{
    Rigidbody rb;
    AudioSource audioS;

    bool rbIsMoving = false;

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        audioS = GetComponent<AudioSource>();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        if (rb.velocity == Vector3.zero)
        {
            Debug.Log("Not moving");
            audioS.volume = 0f;
        }
        else
        {
            Debug.Log("Moving");
            audioS.volume = 0.1f;
        }
    }
}

编辑:我刚刚发现如果玩家将可推动物体推入墙壁,声音仍在播放,因此我认为我也必须改变方式来确定物体是否在移动。

这是由于单精度浮点数造成的

你永远(不应该)直接比较两个float值,因为它们在逻辑上可能是相等的(例如1 = 5*0.2 ),但对于计算机它们可能会有一个小的“epsilon”不同

因此 Unity 决定Vector3仅使用0.00001的精度来表示==


而是使用Mathf.Approximately ,它使用一个非常小的Epsilon


比将rb.velocity每个组件与0进行比较更容易,您真正想要的是rb.velocity.magnitude ,它实际上是整体速度。

if (Mathf.Approximately(rb.velocity.magnitude, 0))

更新

或者存储最后一个位置并使用Vector3.Distance将其与当前位置进行比较,或者再次使用Mathf.Approximately

private Vector3 lastPosition;

private void LateUpdate()
{
    if(Mathf.Approximately(Vector3.Distance(lastPosition, transform.position), 0))
    {
        //...
    }
    else
    {
        //...
        lastPosition = transform.positiom;
    }
}

或者使用自定义阈值

if(Vector3.Distance(lastPosition, transform.position) <= someThreshold)

或者这次你实际上可以使用==如果0.00001的阈值是你想要的

if(lastPosition == transform.position)

您可以检查 RigidBody 是否正在休眠:

if (!rb.IsSleeping()
{
//it's moving
}
else
{
//it's not
}

或者检查自上一帧以来变换位置是否已移动:

Vector3 lastposition;
Gameobject go = somegameobject; 

function Update()
{
    if (lastposition == go.transform.position)
    {
     //not moving
    }
    else
    {
     //moving
    }
    lastposition = go.transform.position;
}

您可以使用Transform.hasChanged检查上次更新时玩家位置是否发生变化

        if (!this.transform.hasChanged)
        {
            print("Player is not moving");
        }
        transform.hasChanged = false;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM