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

Unity OnBecameVisible问题:穿墙检测及场景视图误触发求助

解决方案

问题根源

  • Renderer.isVisible 和 OnBecameVisible/OnBecameInvisible 会响应所有相机,包括Unity编辑器的场景视图相机,测试时自然会误触发。
  • 这俩API只判断物体是否在相机视锥范围内,不检测遮挡物,所以墙后的敌人也会被判定为可见。

修正方案

要实现需求,得同时做到两点:

  1. 只针对玩家主相机判断可见性,排除场景视图的编辑器相机。
  2. 加视线遮挡检测,确保敌人和玩家之间没障碍物,且真在玩家相机视野里。

修改后的代码

using UnityEngine;
using UnityEngine.AI;

public class EnemyChase : MonoBehaviour
{
    public NavMeshAgent enemy;
    public Transform player;
    // 直接拖入玩家相机,比Camera.main更靠谱
    public Camera playerCamera; 

    private Renderer m_Renderer;

    private void Start()
    {
        m_Renderer = GetComponent<Renderer>();
        // 没指定相机的话自动取主相机
        if (playerCamera == null)
        {
            playerCamera = Camera.main;
        }
    }

    private void Update()
    {
        // 只在玩家按空格键时检测
        if (Input.GetKey(KeyCode.Space))
        {
            // 1. 先判断敌人是否在玩家相机的画面范围内,且在相机前方
            Vector3 viewportPos = playerCamera.WorldToViewportPoint(transform.position);
            bool isInCameraView = viewportPos.x >= 0 && viewportPos.x <= 1 
                                && viewportPos.y >= 0 && viewportPos.y <= 1 
                                && viewportPos.z > 0;

            // 2. 再检测敌人是否没被遮挡,真的能被玩家看到
            bool isVisibleToPlayer = false;
            if (isInCameraView)
            {
                RaycastHit hit;
                Vector3 direction = transform.position - playerCamera.transform.position;
                // 从相机射射线到敌人,看是不是直接命中敌人
                if (Physics.Raycast(playerCamera.transform.position, direction.normalized, out hit, direction.magnitude))
                {
                    isVisibleToPlayer = hit.transform == transform;
                }
            }

            // 满足条件就追玩家,不然可以停住
            if (isVisibleToPlayer)
            {
                Debug.Log("敌人可见,开始追逐");
                enemy.SetDestination(player.position);
            }
            else
            {
                Debug.Log("敌人不可见,停止追逐");
                enemy.SetDestination(transform.position);
            }
        }
    }
}

关键细节说明

  • 玩家相机指定:直接拖入玩家相机组件,避免Camera.main在场景多相机时出错。
  • 视口范围判断:用WorldToViewportPoint把世界坐标转成0-1的视口坐标,确保敌人在相机画面内,z>0保证在相机前方。
  • 射线遮挡检测:从相机射射线到敌人,只有射线直接命中敌人时,才判定没遮挡。还可以给射线加层级过滤,比如只检测墙壁层,忽略敌人和玩家,让检测更精准。

额外优化建议

  • 如果敌人是多部件的模型,可以用Physics.SphereCast代替射线,检测范围更大,避免射线偏移导致误判。
  • 可以加个延迟检测,比如每0.1秒检测一次,减少Update里的性能消耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:02:59