Unity使用Vector3.MoveTowards控制弹丸移动速度不恒定问题咨询
问题根因
你观察到的速度不一致是视角下的位移分量错觉,Vector3.MoveTowards本身的逻辑完全符合恒定速度要求,问题出在目标点的Z轴赋值和弹丸初始Z值不匹配:
- 调用
Camera.main.ScreenToWorldPoint(Input.mousePosition)转换坐标时,输入的Input.mousePosition默认Z值为0,代表相机近裁剪面的深度,你手动将target.z固定为10f,但生成弹丸的shotPoint.position的Z值大概率不等于10f - 此时
Vector3.MoveTowards会同时计算XYZ三个轴的移动,三维空间的总移动速度确实是你设置的5f,但你在游戏视口中只能观察到XY轴向的位移分量:- 目标点距离发射器远时,XY轴位移占总位移的比例高,看起来移动快
- 目标点距离发射器近时,XY轴位移占总位移的比例低,看起来移动慢
修复方案
方案1(适配2D游戏,最常用)
保证目标点和弹丸的Z值完全一致,所有移动都落在XY平面,修改发射器的Shooting方法中目标点赋值逻辑:
private void Shooting() { if (Input.GetMouseButton(0)) { if (Time.time >= shotTime) { GameObject poison = Instantiate(Projectile, shotPoint.position, transform.rotation); // 转换屏幕坐标时直接用弹丸的Z值作为深度参数 Vector3 mousePos = Input.mousePosition; mousePos.z = Camera.main.WorldToScreenPoint(shotPoint.position).z; Vector3 target = Camera.main.ScreenToWorldPoint(mousePos); poison.GetComponent<PoisonBall>().target = target; shotTime = Time.time + timeBetweenShots; } } }
方案2(适配3D游戏固定飞行平面)
如果是3D游戏要求弹丸在指定Z平面飞行,修改弹丸移动逻辑,只计算XY轴的移动:
public float speed = 5f; public Vector3 target = new Vector3(); private float initZ; void Start() { // 缓存弹丸初始Z值,全程固定 initZ = transform.position.z; } void Update() { Vector2 current2DPos = new Vector2(transform.position.x, transform.position.y); Vector2 target2DPos = new Vector2(target.x, target.y); Vector2 new2DPos = Vector2.MoveTowards(current2DPos, target2DPos, speed * Time.deltaTime); transform.position = new Vector3(new2DPos.x, new2DPos.y, initZ); }
补充:到达目标点销毁逻辑
在弹丸的Update中追加到达判定即可实现需求:
void Update() { transform.position = Vector3.MoveTowards(transform.position, target,speed * Time.deltaTime); // 距离小于阈值判定为到达,直接销毁 if(Vector3.Distance(transform.position, target) < 0.01f) { Destroy(gameObject); } }
内容的提问来源于stack exchange,提问作者agentsmith200
相关产品推荐
相关产品推荐

