Unity中Projectile穿过Wall无法触发碰撞停止问题求助
解决Projectile穿过Wall的碰撞问题
核心原因
Transform.Translate是直接修改物体的位置坐标,完全绕开了Unity的物理碰撞检测系统,所以即便两个物体都有Collider,也不会触发碰撞事件,导致穿模。
解决方案
方法一:使用Rigidbody控制运动(推荐,符合物理系统逻辑)
- 配置组件:确保Projectile拥有
Rigidbody组件,取消勾选Use Gravity(如果不需要重力影响),将Collision Detection设置为Continuous或Continuous Dynamic(避免高速物体穿模)。 - 替换运动代码:移除
Transform.Translate,改用Rigidbody的物理方法控制运动:
如果需要持续推进力(比如火箭类),则在public Rigidbody rb; public float speed; void Start() { rb = GetComponent<Rigidbody>(); // 给物体一个初始向前的速度 rb.velocity = transform.forward * speed; }FixedUpdate中添加力:void FixedUpdate() { rb.AddForce(transform.forward * speed); } - 添加碰撞停止逻辑:在Projectile的脚本中加入碰撞检测事件,碰到Wall时停止运动:
void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Wall")) // 给Wall添加"Wall"标签 { rb.velocity = Vector3.zero; // 清零速度 rb.isKinematic = true; // 锁定物体,防止后续物理影响 // 也可以直接禁用脚本或物体:this.enabled = false; } }
方法二:保留Transform移动(仅适合低速、简单场景)
如果必须用Transform.Translate,需要手动提前检测碰撞,避免穿模:
public Transform trans; public float speed; public float checkDistance = 0.5f; // 检测前方的距离,根据物体大小调整 void Update() { RaycastHit hit; // 从物体位置向前发射射线,检测是否碰到Wall if (Physics.Raycast(trans.position, trans.forward, out hit, checkDistance)) { if (hit.collider.gameObject.CompareTag("Wall")) { return; // 碰到墙就停止移动 } } // 未检测到障碍物时才移动 trans.Translate(0, 0, speed * Time.deltaTime, Space.Self); }
额外检查项
- 确认Wall的Collider处于启用状态,若使用
Mesh Collider需勾选Convex(静态物体可忽略,但动态碰撞体必须勾选)。 - 确认Projectile的Collider处于启用状态,若勾选
Is Trigger,则需将碰撞事件改为OnTriggerEnter。 - 再次核对Layer碰撞矩阵,确保Projectile和Wall所在的Layer允许互相碰撞。
内容的提问来源于stack exchange,提问作者PHOENIX33201
相关产品推荐
相关产品推荐

