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

Unity使用Vector2.MoveTowards移动时BoxCollider2D触发器不触发问题

Unity2D触发器未触发问题解决方案

核心差异说明

Unity 2D物理(基于Box2D)和3D物理(基于PhysX)的碰撞检测逻辑存在本质区别:3D PhysX会对静态碰撞器的transform位移做额外的碰撞校验,直接修改transform也能触发碰撞/触发器;但2D Box2D的所有碰撞检测完全依赖物理系统的运动模拟,直接修改transform的位移会被物理系统判定为「瞬移」,不会计算位移过程中的碰撞重叠,这是你逻辑在3D生效2D失效的核心原因。

你当前存在的两个关键问题

  • Rigidbody2D的simulated开关处于关闭状态:该开关关闭后,当前物体的Rigidbody2D和所有挂载的2D碰撞器会完全脱离物理系统计算,物理引擎不会识别到该物体的存在,自然不会触发任何碰撞回调。
  • 直接修改transform.position实现移动:就算开启simulated,直接修改transform的位移不会被物理系统识别为合法运动,不会触发路径上的碰撞检测。

正确修复步骤

1. 调整Rigidbody2D参数

  • 打开simulated开关
  • 不需要受物理外力的话,把BodyType改为Kinematic(比Dynamic性能更高,专门用于开发者手动控制移动、同时需要参与碰撞检测的场景),同时设置Gravity Scale = 0,按需开启Constraints下的位置、旋转冻结选项。

2. 修改移动逻辑

将移动代码从Update移到物理更新帧FixedUpdate中,使用Rigidbody2D.MovePosition()接口实现移动,示例修改如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MonsterController : MonoBehaviour
{
    private MonsterInformation info;
    private bool isMoving;
    private Vector2 wantedPosition; // 改用Vector2适配2D物理
    private Vector2 MaxPosition;
    private Vector2 MinPosition;
    private bool isAttacking;
    private Rigidbody2D rb; // 新增Rigidbody2D引用

    void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Start()
    {
        info = MonsterDatabase.Instance.MonsterLookup("Slime");
        MaxPosition = new Vector2(transform.position.x + info.WanderingDistance, 
transform.position.y + info.WanderingDistance);
        MinPosition = new Vector2(transform.position.x - info.WanderingDistance, 
transform.position.y - info.WanderingDistance);
    }

    public void Update()
    {
        if(!isMoving && !isAttacking)
        {
            wantedPosition.x = Random.Range(MinPosition.x, MaxPosition.x);
            wantedPosition.y = Random.Range(MinPosition.y, MaxPosition.y);
            isMoving = true;
        }
     }

    // 移动逻辑移到FixedUpdate执行
    private void FixedUpdate()
    {
        if(isAttacking || !isMoving) return;
        rb.MovePosition(Vector2.MoveTowards(rb.position, wantedPosition, Time.fixedDeltaTime * info.WalkingSpeed));
        // 浮点计算存在误差,不要直接判断等于,用距离阈值判断是否到达目标点
        if(Vector2.Distance(rb.position, wantedPosition) < 0.01f)
        {
            isMoving = false;
        }
    }

    public void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log($"Triggered {other.name}");
    }
 }

3. 额外校验项

  • 确认参与碰撞的两个物体中,至少有一个挂载了开启simulated的Rigidbody2D(2D物理触发的必要条件,3D无此要求)
  • 确认至少一方的BoxCollider2D开启了Is Trigger选项
  • 确认两个物体所在Layer在2D碰撞矩阵中是允许碰撞的

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:36:02