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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:24:02