Unity中CharacterController与普通碰撞体无法碰撞的问题求助
问题核心原因
你混淆了Unity的3D和2D物理系统——3D的CharacterController属于3D物理体系,和2D碰撞体/刚体完全不兼容,两者是独立运行的物理模块,不会互相触发碰撞检测。你检查的Physics2D层碰撞矩阵只对2D组件生效,对3D的CharacterController毫无作用。
解决方案
方案1:统一使用3D物理系统(保留CharacterController)
- 玩家保持挂载
CharacterController(3D组件) - 地面对象使用3D的Box Collider,无需额外添加Rigidbody(静态碰撞体默认会被3D物理系统识别)
- 检查3D物理的层碰撞矩阵:打开
Edit > Project Settings > Physics(不是Physics2D),确认Default层与自身的碰撞选项已勾选 - 重力模拟逻辑保持用
_controller.Move()的方式,注意3D环境中重力方向为Vector3.down,确保_velocity的计算符合3D坐标系
方案2:切换到2D物理系统(适合2D游戏场景)
- 移除玩家的
CharacterController,替换为Rigidbody2D(根据需求设置为Kinematic或Dynamic)+ 2D碰撞体(如CapsuleCollider2D) - 地面对象使用2D的BoxCollider2D,若为静态地面,将其Rigidbody2D设置为Static
- 移动逻辑调整:
- 若用Kinematic刚体,使用
rb.MovePosition()或直接修改transform.position - 若用Dynamic刚体,通过
rb.AddForce()或修改rb.velocity实现移动
- 若用Kinematic刚体,使用
- 确保所有碰撞体、刚体都是2D类型,再检查
Physics2D的层碰撞矩阵
额外排查要点
- 确认玩家和地面的碰撞体未被禁用,且碰撞体的大小、位置正确覆盖模型区域
- 调整
CharacterController的Skin Width参数(建议设为碰撞体半径的10%左右),过小的Skin Width容易导致穿透问题 - 检查
_velocity的重力数值是否过大,或Time.fixedDeltaTime的计算是否有误,这也可能导致低速下的穿透
内容的提问来源于stack exchange,提问作者H Salih Toker
相关产品推荐
相关产品推荐

