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

Vector3.MoveTowards实现跟随光标移动时无法触发2D碰撞检测怎么办?

解决方案

问题原因

直接通过transform.position赋值移动物体,相当于绕开了Unity 2D物理引擎的计算流程,物理引擎无法感知物体的移动路径,速度较快时会直接跳过碰撞体,导致碰撞回调无法触发。

前置配置检查

  • 飞机节点必须挂载Rigidbody2D组件,同时挂载对应形状的碰撞体(如BoxCollider2D/PolygonCollider2D),不要勾选碰撞体的Is Trigger属性
  • 与飞机碰撞的目标物体必须挂载碰撞体,若目标为场景静态障碍物无需加刚体,若为动态物体也需要挂载Rigidbody2D
  • 调整Rigidbody2D属性:
    • Gravity Scale设为0,避免飞机受重力影响下坠
    • Body Type设为Dynamic,Kinematic类型刚体无法与静态碰撞体触发碰撞回调
    • 若移动速度非常快,可将Collision Detection改为Continuous,开启连续碰撞检测避免穿模

代码修改方案

将移动逻辑从Update移到物理更新周期的FixedUpdate中,通过Rigidbody2D提供的方法控制移动与旋转,保证物理引擎参与全部计算:

public float speed = 5f;
public float rotationOffset = -90f;
private Rigidbody2D rb;

private void Awake()
{
    // 获取刚体组件引用
    rb = GetComponent<Rigidbody2D>();
}

private void Update()
{
    // 角度计算保留在Update,保证旋转响应跟手
    Vector3 mousePos = Input.mousePosition;
    Vector3 objectPos = Camera.main.WorldToScreenPoint(transform.position);
    mousePos.x -= objectPos.x;
    mousePos.y -= objectPos.y;
    float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
    // 改用刚体方法控制旋转
    rb.MoveRotation(angle + rotationOffset);
}

private void FixedUpdate()
{
    // 移动逻辑放在FixedUpdate,和物理更新同步
    Vector3 targetPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    targetPos.z = 0;
    // 用刚体MovePosition替代直接修改transform.position
    Vector2 newPos = Vector3.MoveTowards(rb.position, targetPos, speed * Time.fixedDeltaTime);
    rb.MovePosition(newPos);

    if (Vector2.Distance(rb.position, targetPos) < 0.01f)
    {
        Die();
    }
}

private void Die()
{
    // 此处保留原有的销毁逻辑
}

private void OnCollisionEnter2D(Collision2D col)
{
    Debug.Log("hit: " + col.gameObject.name);
}

额外注意事项

  • 确保飞机和碰撞目标的Z轴差值不超过0.01,2D碰撞体默认厚度极小,Z轴相差过大也会导致检测失效
  • 不要同时在代码里修改transform的位置/旋转和刚体的位置/旋转,两者冲突会导致物理计算异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 00:48:05