Unity中子弹移动时transform.position与目标终点位置判断永远不相等问题
问题原因
- 浮点数精度误差:Unity中
Vector3的==判断要求三个轴向的浮点值完全相等,而游戏运行中的位置计算存在天然的浮点精度误差,几乎不可能和预设的BulletEndDist完全匹配。 - 步长跳点问题:你每帧移动的距离是固定值,大概率会出现当前帧还在终点前,下一帧就直接越过终点的情况,永远不会刚好停在
BulletEndDist坐标上。 - 执行顺序逻辑问题:现有代码先做到达判断,再执行位移,哪怕刚好位移到终点位置,也要等到下一帧才会触发判断,进一步提升了跳点概率。
- 位移未适配帧率:位移代码没有乘
Time.deltaTime,子弹移动速度会随帧率波动变化,进一步放大位置计算误差。
解决方案
把完全相等的坐标判断替换为距离阈值判断,调整位移和判断的执行顺序,同时给位移加上时间缩放适配:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class BulletScript : MonoBehaviour { [SerializeField] PlayerAttacking PA; [SerializeField] float speed; // 阈值可根据实际需求调整,越小判断越精准 [SerializeField] float destroyThreshold = 0.05f; Vector3 BulletEndDist; // Start is called before the first frame update void Start() { PA = GameObject.Find("AttackTrail").GetComponent<PlayerAttacking>(); BulletEndDist = transform.position + (transform.forward * PA.TrailDistance) ; } // Update is called once per frame void Update() { // 先执行位移 transform.Translate(new Vector3(0, 0, speed * Time.deltaTime)); // 用距离小于阈值代替完全相等判断 if(Vector3.Distance(transform.position, BulletEndDist) <= destroyThreshold) { Destroy(this.gameObject); } } private void OnCollisionEnter(Collision collision) { if(collision.transform.tag == "Enemy") { // Decrease health Destroy(this.gameObject); } else { Destroy(this.gameObject); } } }
如果追求更高的运行效率,可以把Vector3.Distance换成平方距离判断,避免开方运算:
if((transform.position - BulletEndDist).sqrMagnitude <= destroyThreshold * destroyThreshold)
内容的提问来源于stack exchange,提问作者AG-88301
相关产品推荐
相关产品推荐

