Unity C#重力计算函数返回NaN值的原因排查求助
Unity引力计算脚本NaN错误排查思路
问题场景
使用以下脚本计算天体间引力时,场景中两个物体均触发Input force is { NaN, NaN, NaN }错误,已确认无明显除零情况,需要排查原因。
脚本代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Gravity : MonoBehaviour { public const float gravity = 10; public float mass = 10f; public bool active = true; public Rigidbody rigidbody; public Transform transform; GameObject[] otherObjs; Gravity[] otherGravities; void Start () { rigidbody = gameObject.GetComponent<Rigidbody>(); transform = gameObject.transform; otherObjs = GameObject.FindGameObjectsWithTag("Body"); otherGravities = new Gravity[otherObjs.Length]; for (int i = 0; i < otherObjs.Length; i++) { otherGravities[i] = otherObjs[i].GetComponent<Gravity>(); } } void FixedUpdate () { rigidbody.AddForce(CalculateGravity()); } Vector3 CalculateGravity () { Vector3 finalGravity = new Vector3(0, 0, 0); foreach (Gravity current in otherGravities) { float distance = Vector3.Distance(transform.position, current.transform.position); Vector3 unNormalDirection = transform.position - current.transform.position; Vector3 direction = unNormalDirection.normalized; Vector3 gravitationalPull = ((mass * current.mass) / (distance * distance)) * direction; finalGravity += gravitationalPull; } return finalGravity; } }
错误信息
rigidbody.force assign attempt for 'Sun' is not valid. Input force is { NaN, NaN, NaN }. UnityEngine.Rigidbody:AddForce (UnityEngine.Vector3) Gravity:FixedUpdate () (at Assets/Scripts/Gravity.cs:27)
排查思路
排除自身对象遍历:
GameObject.FindGameObjectsWithTag("Body")会将挂载该脚本的自身(如果标签为Body)也加入数组。当遍历到自身时,Vector3.Distance返回0,此时对零向量执行normalized操作会直接得到(NaN, NaN, NaN),最终导致引力计算结果为NaN。需在遍历前添加判断跳过自身:foreach (Gravity current in otherGravities) { if (current == this) continue; // 跳过自身 // 剩余计算逻辑 }校验数组元素有效性:若场景中存在标签为Body但未挂载Gravity脚本的物体,
otherGravities数组会包含null元素。遍历到null时访问current.transform会引发空引用,虽不一定直接导致NaN,但会破坏计算逻辑。建议在Start方法中筛选有效组件,改用List存储:List<Gravity> validGravities = new List<Gravity>(); foreach (var obj in otherObjs) { Gravity comp = obj.GetComponent<Gravity>(); if (comp != null && comp != this) { validGravities.Add(comp); } } otherGravities = validGravities.ToArray();检查质量与距离的合法性:
- 确认所有物体的
mass值未被设置为NaN或无穷大,可在CalculateGravity中添加日志输出mass和current.mass的值验证。 - 即使排除了自身,若两物体位置完全重合(距离为0),零向量归一化仍会产生NaN。需添加距离阈值判断,跳过极近距离的计算:
float distance = Vector3.Distance(transform.position, current.transform.position); if (distance < 0.001f) continue; // 跳过极近距离,避免异常
- 确认所有物体的
修正引力方向逻辑:当前代码中
unNormalDirection = transform.position - current.transform.position得到的是远离对方的方向,与引力“相互吸引”的逻辑相反。虽不会导致NaN,但会引发物理行为异常,建议修正为:Vector3 unNormalDirection = current.transform.position - transform.position;确认常量
gravity的使用:脚本中定义了gravity常量但未参与计算,实际引力公式缺少引力系数,需补全:Vector3 gravitationalPull = (gravity * mass * current.mass) / (distance * distance) * direction;
内容的提问来源于stack exchange,提问作者Ninju4821
相关产品推荐
相关产品推荐

