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

Unity中如何基于主体对象可见性控制眼睛渲染器的更新?

问题

我用了一个挂载眼睛对象的Rig,后续模型会有大量移动操作,比如头部会碰到地面,眼睛也会跟着移动。现在遇到个问题:对象原点在绑定姿态的头部位置,当模型头部下移、拉近视角观察眼睛,直到原点移出视野时,眼睛就会消失,只有把视角转回原点位置才会重新显示。这个问题在Scene视图和Game视图里都出现。

我考虑过开启updateWhenOffscreen,但担心影响性能,所以想基于更容易保持在视野里的主体对象来决定更新剔除规则。但Unity 2021.3.5f1里这个选项只有复选框,没有可修改的字段,而且我不太会添加自定义字段。

我试着写了下面的脚本,挂载到主体上并关联眼睛的SkinnedMeshRenderer,但没达到预期效果:就算主体在视野里,眼睛还是会在两个视图中消失。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UpdateRendererOverrideManager : MonoBehaviour
{
    public SkinnedMeshRenderer eye;

    private void OnBecomeVisible()
    {
        eye.updateWhenOffscreen = true;
    }
    private void OnBecomeInvisible()
    {
        eye.updateWhenOffscreen = false;
    }

}

(附脚本组件截图及Game视图眼睛未渲染截图)


解决方案

问题根源

你的脚本没生效,是因为OnBecomeVisible/OnBecomeInvisible只有在挂载脚本的对象自身带有渲染组件(比如MeshRenderer、SkinnedMeshRenderer)时才会触发。如果主体对象本身没有渲染器,这两个方法根本不会被调用,自然没法控制眼睛的updateWhenOffscreen属性。

修复方案

方案1:给主体添加不可见渲染器触发事件

在主体对象上添加MeshRenderer和MeshFilter组件,使用一个极小的平面Mesh或者空Mesh,然后将材质的Alpha值设为0,同时勾选ShadowCastingMode为Off、取消勾选Receive Shadows,确保它不会影响画面显示。这样OnBecomeVisible/OnBecomeInvisible就能正常触发,你的原脚本就能生效。

方案2:手动检测主体是否在相机视野内

如果不想给主体加额外组件,可以改用GeometryUtility.TestPlanesAABB手动判断主体包围盒是否在相机视野内,修改后的脚本如下:

using UnityEngine;

public class UpdateRendererOverrideManager : MonoBehaviour
{
    public SkinnedMeshRenderer eye;
    private Camera mainCamera;

    private void Start()
    {
        mainCamera = Camera.main;
    }

    private void Update()
    {
        // 获取主体的包围盒,优先用Renderer,没有则用Collider
        Bounds bounds;
        var renderer = GetComponent<Renderer>();
        if (renderer != null)
        {
            bounds = renderer.bounds;
        }
        else
        {
            var collider = GetComponent<Collider>();
            bounds = collider != null ? collider.bounds : new Bounds(transform.position, Vector3.one * 0.1f);
        }

        // 检测主体是否在当前相机视野内
        bool isVisible = GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(mainCamera), bounds);
        
        eye.updateWhenOffscreen = isVisible;
    }
}

方案3:平衡性能与显示的简化处理

如果能接受轻微性能损耗,直接开启眼睛的updateWhenOffscreen,然后在Project Settings -> Quality中调整Skinned Mesh Update Rate,降低非视野内皮肤网格的更新频率,以此平衡性能开销和显示效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:15:48