[英]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.