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

Unity火箭着陆游戏碰撞检测失效问题求助

碰撞检测失效排查与修复方案

一、核心设置问题(最可能的触发失效原因)

  • 脚本挂载位置错误
    你的LandingBehaviour脚本如果挂载在Rocket物体上,而Rocket本身没有Collider,碰撞事件不会触发在Rocket的脚本上——尽管Rocket有Rigidbody,但碰撞发生在子物体Thruster/RocketBody的Collider上。Unity中碰撞事件优先发送给碰撞体所在的物体,带Rigidbody的父物体若无自身Collider,可能无法触发碰撞事件。
    修复:将脚本挂载到Thruster或RocketBody上,或者给Rocket添加与火箭形状匹配的Collider(比如Box Collider)。

  • 碰撞体初始重叠问题
    若场景初始化时,火箭子物体的Collider与着陆台/地面的Collider已重叠,Unity会跳过初始碰撞事件的触发。
    修复:调整火箭初始位置,确保所有Collider在游戏启动时无重叠。

二、代码逻辑错误(即使碰撞触发也无法正常工作)

  1. 碰撞标签判断逻辑完全错误
    原代码中:

    if (!collision.gameObject.CompareTag("LandingPad") || !collision.gameObject.CompareTag("Ground"))
    {
        return;
    }
    

    用||(逻辑或)意味着只要碰撞对象不是着陆台,或者不是地面,就直接返回。但任何对象不可能同时是着陆台和地面,因此这个条件永远为true,会直接跳过后续所有逻辑。
    修复:改为&&(逻辑与),表示既不是着陆台也不是地面时才返回:

    if (!collision.gameObject.CompareTag("LandingPad") && !collision.gameObject.CompareTag("Ground"))
    {
        return;
    }
    
  2. 冻结刚体的代码写反
    你需要碰撞后冻结运动,应将Rigidbody设为运动学,但原代码写的是:

    _rigidBody.isKinematic = false;
    

    修复:改成true:

    _rigidBody.isKinematic = true;
    
  3. 着陆台类型判断逻辑错误
    原脚本中_greenPad/_yellowPad/_redPad属于挂载脚本的物体(比如火箭),而非碰撞到的着陆台,逻辑完全不符合需求。
    修复:给不同颜色的着陆台分别设置标签(如GreenPad、YellowPad、RedPad),碰撞时直接判断标签:

    if (collision.gameObject.CompareTag("GreenPad"))
    {
        Debug.Log("Green Landing Pad Found.");
        _score *= 2;
    }
    else if (collision.gameObject.CompareTag("YellowPad"))
    {
        Debug.Log("Yellow Landing Pad Found.");
        _score *= 3;
    }
    else if (collision.gameObject.CompareTag("RedPad"))
    {
        Debug.Log("Red Landing Pad Found.");
        _score *= 5;
    }
    
  4. 旋转判断单位错误
    transform.rotation.z获取的是四元数分量(范围[-1,1]),不是角度值。需转换成欧拉角的z轴角度:

    float zAngle = collision.gameObject.transform.eulerAngles.z;
    // 转换为-180到180的角度范围
    zAngle = (zAngle > 180) ? zAngle - 360 : zAngle;
    if (Mathf.Abs(zAngle) >= 45)
    {
        _crash = true;
    }
    

三、完整修复后的代码示例

using UnityEngine;

public class LandingBehaviour : MonoBehaviour
{
    private bool _crash = false;
    private float _score = 1;
    [SerializeField] private Rigidbody _rigidBody;

    private void Awake()
    {
        // 若脚本挂载在子物体,自动获取父物体的Rigidbody
        if (_rigidBody == null)
        {
            _rigidBody = GetComponentInParent<Rigidbody>();
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        Debug.Log("A collision has occurred.");

        // 冻结刚体,停止所有物理运动
        _rigidBody.isKinematic = true;

        // 过滤非目标碰撞对象
        if (!collision.gameObject.CompareTag("GreenPad") && 
            !collision.gameObject.CompareTag("YellowPad") && 
            !collision.gameObject.CompareTag("RedPad") && 
            !collision.gameObject.CompareTag("Ground"))
        {
            return;
        }

        // 判断着陆台是否倾斜过度
        float zAngle = collision.gameObject.transform.eulerAngles.z;
        zAngle = (zAngle > 180) ? zAngle - 360 : zAngle;
        if (Mathf.Abs(zAngle) >= 45)
        {
            _crash = true;
        }

        // 计算得分
        if (collision.gameObject.CompareTag("GreenPad"))
        {
            Debug.Log("Green Landing Pad Found.");
            _score *= 2;
        }
        else if (collision.gameObject.CompareTag("YellowPad"))
        {
            Debug.Log("Yellow Landing Pad Found.");
            _score *= 3;
        }
        else if (collision.gameObject.CompareTag("RedPad"))
        {
            Debug.Log("Red Landing Pad Found.");
            _score *= 5;
        }
        else if (collision.gameObject.CompareTag("Ground"))
        {
            Debug.Log("Ground Found.");
            _score *= 1;
        }

        // 此处添加显示得分、重试/退出按钮的逻辑
        // ShowScorePanel();
        // ShowControlButtons();
    }
}

最后验证步骤

  1. 将脚本挂载到Thruster或RocketBody上,或给Rocket添加自身Collider
  2. 给不同颜色着陆台设置对应标签(GreenPad/YellowPad/RedPad),地面设置Ground标签
  3. 运行游戏,查看Console是否输出碰撞日志,检查刚体是否冻结
  4. 测试不同着陆台的得分计算是否正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:52:51