Unity中调用Mathf.Acos为何返回NaN值?求技术解决方案
解决Unity中Mathf.Acos返回NaN的问题
嘿,我一眼就发现问题出在哪了!你的Mathf.Clamp调用参数顺序完全搞反了,这就是导致Mathf.Acos返回NaN的核心原因。
问题分析
Mathf.Clamp的正确语法是:Mathf.Clamp(要钳制的数值, 最小值, 最大值),但你写的是:
a = Mathf.Clamp(-1, a, 1);
这相当于把-1作为要钳制的目标,把a当成了最小值——这完全起不到你想要的、把a限制在[-1, 1]范围内的作用。当a的数值因为浮点精度问题(比如计算后略大于1或略小于-1)超出范围时,Mathf.Acos接收到非法输入,自然就返回NaN了。
修正后的代码
把Clamp的参数顺序调整过来就好,同时建议用-1f和1f明确指定浮点类型,避免隐式转换问题:
float a = Vector3.Dot(waterlineVec.normalized, transform.InverseTransformDirection(velocityVector.normalized)); a = Mathf.Clamp(a, -1f, 1f); // 正确顺序:目标值在前,min和max在后 alpha = Mathf.Acos(a); // alpha in radians
额外的调试与防护建议
- 添加日志验证:可以在Clamp后加一行日志,确认数值确实被正确限制:
Debug.Log($"Clamped a value: {a}"); - 零向量检查:如果
waterlineVec或velocityVector是零向量,调用normalized会返回零向量,Dot计算结果可能依然异常,建议提前做判断:// 用sqrMagnitude判断零向量,比magnitude更高效 if (waterlineVec.sqrMagnitude < 0.0001f || velocityVector.sqrMagnitude < 0.0001f) { // 根据你的业务逻辑给alpha设置默认值,比如0或Mathf.PI/2 alpha = 0f; return; } float a = Vector3.Dot(waterlineVec.normalized, transform.InverseTransformDirection(velocityVector.normalized)); a = Mathf.Clamp(a, -1f, 1f); alpha = Mathf.Acos(a);
内容的提问来源于stack exchange,提问作者DjAndyC
相关产品推荐
相关产品推荐

