You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:55:48