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

Unity 3D开发中OnCollisionEnter碰撞回调不触发问题求助

问题现象

编写的3D项目碰撞检测脚本无法正常触发OnCollisionEnter回调,对应脚本代码如下:

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

public class Collision : MonoBehaviour
{
    private void OnCollisionEnter(UnityEngine.Collision other)
    {
        if(other.gameObject.tag == "Wrong")
        {
           print("test");
        }
    }
}

当前已知配置:参与碰撞的两个对象的BoxCollider组件isTrigger属性均设置为false。

疑问点
  • 玩家使用胶囊体碰撞体是否会影响碰撞检测
  • 玩家挂载的Rigidbody组件isKinematic属性为True,且使用Character Controller实现移动逻辑,是否会导致回调不触发
  • 未定位到问题根因,需要对应解决方案
根因说明
  1. 胶囊体作为玩家碰撞体不会影响碰撞检测,是Unity 3D角色开发的标准碰撞体配置,不存在兼容问题。
  2. 当前配置确实会导致OnCollisionEnter无法触发,核心原因有两点:
    • 不符合Unity物理碰撞事件规则:两个碰撞体要触发OnCollisionEnter回调,必须保证至少有一个碰撞体挂载非Kinematic状态的Rigidbody。两个Kinematic Rigidbody之间、Kinematic Rigidbody和无Rigidbody的静态碰撞体之间,都不会派发碰撞进入事件。
    • 组件逻辑冲突:CharacterController自带独立的碰撞检测逻辑,移动完全由该组件接管,不会走常规Rigidbody的物理碰撞事件派发流程。同时挂载Rigidbody和CharacterController属于典型的混用两套物理系统的错误写法,常规物理回调默认不会触发。
  3. 额外隐患:脚本类名直接命名为Collision,和Unity内置的UnityEngine.Collision类重名,虽然当前参数写了全限定名没有触发编译错误,但后续开发很容易引发命名冲突。
可落地解决方案
  • 优先推荐方案(适配现有CharacterController移动逻辑):
    删掉玩家对象上挂载的Rigidbody组件,不要混用两套物理系统。CharacterController的碰撞事件不要用OnCollisionEnter监听,改用组件自带的OnControllerColliderHit回调实现碰撞判断,参考代码:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    // 建议把类名改成和引擎类不冲突的自定义名称
    public class PlayerCollision : MonoBehaviour
    {
        private CharacterController _characterController;
        void Awake()
        {
            _characterController = GetComponent<CharacterController>();
        }
    
        private void OnControllerColliderHit(ControllerColliderHit hit)
        {
            if(hit.gameObject.CompareTag("Wrong"))
            {
                print("test");
            }
        }
    }
    
    注意判断标签优先用CompareTag方法,比直接取tag字段判断性能更好,还能在标签不存在时抛出告警,避免手写标签名拼错的问题。
  • 备选方案(适配常规物理系统回调):
    删掉玩家对象上的CharacterController组件,将挂载的Rigidbody的isKinematic属性设为false,通过Rigidbody提供的MovePosition等API实现移动逻辑。此时只要保证两个碰撞对象至少有一个挂载非Kinematic Rigidbody,OnCollisionEnter就可以正常触发。
  • 通用排查项:
    打开Edit > Project Settings > Physics面板,检查碰撞矩阵中两个碰撞对象所属Layer的交互是否勾选,层交互被屏蔽也会导致碰撞事件不触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:15:38