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

Unity射线检测无法触发OnTriggerEnter()的问题求助

问题原因与解决办法

核心问题根源

OnTriggerEnter() 是Unity的物理触发回调,它的触发逻辑是:只有当带有Rigidbody组件的碰撞体实体进入触发器(Is Trigger开启的碰撞体)时,才会调用这个函数。而你用的Physics.Raycast()是射线投射检测,本质是一种"虚拟射线命中检测",不属于物理实体间的碰撞交互,所以完全不会触发OnTriggerEnter()——这就是射线能命中雾碰撞体,但雾的回调没反应的原因。


解决办法一:直接在射线检测中处理雾隐藏

这种方式适合单射线的视野检测逻辑,直接在射线命中时获取雾对象并执行隐藏操作:

1. 修改雾的脚本(FogTmp)

添加公开的隐藏方法,供外部调用:

using UnityEngine;

public class FogTmp : MonoBehaviour
{
    // 公开方法,用于隐藏当前雾对象
    public void HideFog()
    {
        // 选择适合的隐藏方式:禁用物体/关闭渲染器/修改透明度等
        gameObject.SetActive(false);
        // 备选:GetComponent<Renderer>().enabled = false;
    }
}

2. 修改单位的射线检测脚本(UnitTmp)

使用带RaycastHit参数的Raycast重载,获取命中对象并判断是否为雾:

using UnityEngine;

public class UnitTmp : MonoBehaviour
{
    public float LoS = 12f;

    private void FixedUpdate()
    {
        RaycastHit hitInfo;
        // 发射射线并获取命中信息
        bool isHit = Physics.Raycast(
            transform.position + new Vector3(1.5f, 0, 0),
            transform.TransformDirection(Vector3.left),
            out hitInfo,
            LoS
        );

        if (isHit)
        {
            Debug.Log("命中对象:" + hitInfo.collider.gameObject.name);
            // 检查命中对象是否挂载了雾脚本
            FogTmp targetFog = hitInfo.collider.GetComponent<FogTmp>();
            if (targetFog != null)
            {
                targetFog.HideFog();
            }
        }

        Debug.DrawRay(
            transform.position + new Vector3(1.5f, 0, 0),
            transform.TransformDirection(Vector3.left) * LoS,
            Color.green
        );
    }
}

解决办法二:用触发器实现范围视野(更适合战争迷雾)

如果你的战争迷雾是范围视野(而非单射线),建议给单位添加一个范围触发器,当雾进入视野范围时自动隐藏:

修改单位脚本(UnitTmp)

using UnityEngine;

public class UnitTmp : MonoBehaviour
{
    public float LoS = 12f;

    private void Start()
    {
        // 动态添加球形视野触发器(也可以手动在Inspector添加)
        SphereCollider visionTrigger = gameObject.AddComponent<SphereCollider>();
        visionTrigger.isTrigger = true;
        visionTrigger.radius = LoS;
        // 调整触发器中心,和你之前的射线起点对齐
        visionTrigger.center = new Vector3(1.5f, 0, 0);
    }

    // 当物体进入视野触发器时触发
    private void OnTriggerEnter(Collider other)
    {
        FogTmp fog = other.GetComponent<FogTmp>();
        if (fog != null)
        {
            fog.HideFog();
            Debug.Log("雾进入视野:" + other.name);
        }
    }
}

额外优化建议

  • 图层过滤:给所有雾对象单独设置一个Fog图层,射线检测或触发器检测时只针对该图层,避免误检测其他物体,提升性能:
    • 射线检测时添加图层掩码:Physics.Raycast(..., out hitInfo, LoS, LayerMask.GetMask("Fog"))
    • 触发器可以在Inspector的Layer Collision Matrix中设置只和Fog图层交互。
  • 视野动态更新:如果需要单位转动时更新视野,方案一可以用多条射线组成扇形检测,方案二可以让触发器随单位旋转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:05:20