Unity C# Vector3.Distance返回非预期结果 0°与360°向量距离不为0
问题成因分析
核心原因:单精度浮点数运算的固有精度误差
所有你描述的现象都是float类型运算的正常表现,不属于bug:
- C#的
float是32位单精度浮点数,只能存储有限精度的数值,π是无限不循环小数,Mathf.Deg2Rad本身就是π/180的近似值。360度转换为弧度后是2*π的近似值,并非数学意义上精确的2π,因此Mathf.Sin(2*π近似值)、Mathf.Cos(2*π近似值)的计算结果和0、1会存在极小的偏差,而非完全相等。 - Unity的
Vector3重载的ToString()方法会对输出的数值做精度截断,因此你在控制台看到两个坐标都是(0.0, 0.0, 1.0),肉眼看不出差异。 - Unity的
Vector3重载的==运算符自带了容错阈值,只要两个向量的分量差值小于1e-5量级就会判定为相等,所以你输出的positions equal结果为True。 Vector3.Distance是严格按照数学公式√((x1-x2)² + (y1-y2)² + (z1-z2)²)计算的,会把分量的微小偏差累加后输出,因此得到了1.748456E-07这个极小的数值,这个数值在实际游戏开发中可以等效为0处理。
适配方案
- 不要直接判断
distance == 0,而是和你业务可接受的极小阈值做比较,比如:if(distance < 0.001f)就判定两点重合。 - 普通位置相等判断直接使用Unity内置的
position1 == position2即可,内置的容错机制已经能满足绝大多数游戏开发场景的需求。 - 计算前可以先对角度做360取模处理,减少大角度带来的额外精度误差:
angle1 = angle1 % 360f; angle2 = angle2 % 360f;
内容的提问来源于stack exchange,提问作者B-and-P
相关产品推荐
相关产品推荐

