当刚体移动时,刚体速度有时为零

问题描述 投票:2回答:2

我正在尝试将声音添加到我的可推送对象中,并且只是有一个简单的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;
        }
    }
}

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

c# unity3d velocity rigid-bodies
2个回答
3
投票

这是因为single precision floating point

你永远不应该(应该)直接比较两个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)

2
投票

你可以检查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;
}
© www.soinside.com 2019 - 2024. All rights reserved.