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

Unity2D中如何让子弹朝鼠标位置持续飞行且速度恒定?

问题根源与解决方法

你的问题确实出在Vector3.MoveTowards()的错误使用上,同时缺少对“发射时鼠标位置”的持久化存储,导致子弹行为异常。

核心问题分析

  1. MoveTowards用法错误:你每帧都将目标点设为transform.position + dir*10f,这个目标点会随子弹位置不断向前移动。当鼠标离玩家较近时,子弹很快会抵达初始鼠标位置,后续的动态目标点会与该位置重叠,子弹便停止移动;当鼠标离玩家较远时,动态目标点始终在子弹前方,子弹看似正常移动,但本质逻辑完全错误,且容易因计算误差导致速度异常。
  2. 未持久化目标位置:你只传递了方向向量,没有保存发射时的鼠标位置,无法准确判断子弹是否抵达目标点。

解决方案

步骤1:修正子弹的移动逻辑

直接使用方向向量实现匀速移动,替代错误的MoveTowards用法:

private Vector3 dir;
private Vector3 targetPos;
// 可根据需求调整速度值
public float speed = 8f;

// 新增初始化方法,接收方向和目标位置
public void Init(Vector3 direction, Vector3 target) {
    dir = direction;
    // 给目标位置加微小偏移,避免浮点精度问题导致无法触发销毁
    targetPos = target + dir * 0.1f;
}

private void Update() {
    // 沿单位方向向量匀速移动,速度完全由speed控制
    transform.position += dir * speed * Time.deltaTime;

    // 检查是否抵达目标位置,销毁子弹
    if (Vector3.Distance(transform.position, targetPos) < 0.1f) {
        Destroy(gameObject);
    }
}

步骤2:修改玩家Shoot函数,传递目标位置

在发射子弹时,将发射瞬间的鼠标位置传递给子弹,而不是只传递方向:

void Shoot() {
    Vector3 pos = transform.position;
    pos.y += 0.5f;
    Bullet newBullet = Instantiate(bullet, pos, bullet.transform.rotation) as Bullet;

    Vector3 mousePos = Input.mousePosition;
    mousePos.z = Camera.main.nearClipPlane;
    // 获取发射时的世界空间鼠标位置
    Vector3 targetPos = Camera.main.ScreenToWorldPoint(mousePos);
    // 计算归一化方向向量
    Vector3 heading = targetPos - pos;
    Vector3 direction = heading.normalized;

    // 初始化子弹,传递方向和目标位置
    newBullet.Init(direction, targetPos);
}

关键说明

  • 改用transform.position += dir * speed * Time.deltaTime后,子弹速度完全由speed变量控制,与鼠标和玩家的距离无关,实现了真正的匀速移动。
  • 通过Init方法传递发射时的目标位置,确保子弹只会在抵达发射瞬间的鼠标位置时销毁,不会受后续鼠标移动影响。
  • 给目标位置添加微小偏移是为了避免浮点精度误差导致子弹无法触发销毁逻辑。

内容的提问来源于stack exchange,提问作者boar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 07:24:25