Unity角色挂载Collider仍无法与场景物体产生碰撞如何解决
问题核心原因
你无法触发碰撞的核心原因是Character Controller 不使用 Unity 原生物理系统的 OnCollisionEnter 碰撞回调机制,你写的碰撞监听方法从根本上就不会被调用。
Character Controller 是 Unity 为角色类移动逻辑单独封装的控制组件,它有独立的碰撞检测逻辑,和 Rigidbody 驱动的物理碰撞体系是两套独立流程,哪怕你同时挂载 Rigidbody、所有碰撞体都正确设置非Trigger,也不会触发原生物理碰撞回调。
修复步骤
- 移除角色上多余的非运动学 Rigidbody 组件。Character Controller 本身自带碰撞体和移动碰撞计算,额外挂载的非Kinematic Rigidbody会和组件抢夺移动控制权,直接导致碰撞失效;如果确实需要保留Rigidbody,请将Rigidbody设置为Is Kinematic模式。
- 替换碰撞监听方法,使用Character Controller专属的
OnControllerColliderHit回调做碰撞检测,注意这个回调只有在你调用Character Controller自带的Move()/SimpleMove()方法驱动角色移动时才会触发,直接修改Transform坐标移动不会触发任何碰撞检测。 - 优先使用
CompareTag()方法做标签判断,避免直接通过collider.tag判断时出现标签拼写错误无报错、逻辑不触发的问题。
修正后的可用代码
using UnityEngine; public class PlayerCollision : MonoBehaviour { private CharacterController _characterController; private void Awake() { // 提前缓存角色身上的CharacterController组件 _characterController = GetComponent<CharacterController>(); } /// <summary> /// CharacterController专属碰撞回调,移动时碰到碰撞体就会触发 /// </summary> /// <param name="hit">碰撞信息</param> private void OnControllerColliderHit(ControllerColliderHit hit) { if (hit.collider.CompareTag("Court")) { Debug.Log("We hit the court"); } } }
额外排查项
如果改完还是不触发碰撞,检查以下配置:
- Character Controller组件的
Skin Width参数不要设置过小,建议设置为半径的10%左右,太小会导致碰撞检测频繁失效穿模 - 角色初始生成位置不要和其他碰撞体重叠,初始嵌入碰撞体的状态下不会触发碰撞回调
- 确认所有需要碰撞的场景物体都挂载了非Trigger的Collider组件,且和角色在同一Layer层级,没有被Layer碰撞矩阵排除碰撞关系
内容的提问来源于stack exchange,提问作者StealthMC
相关产品推荐
相关产品推荐

