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

异步加载场景后Unity反向遮罩图片失效问题排查

问题

异步加载场景后,自定义反向遮罩的UI元素无法显示,但禁用再重新启用该对象后就能正常显示。请问为什么自定义的反向遮罩类在异步加载场景后会失效?

对应的自定义反向遮罩图片类代码:

public class CutOutImage : Image
{
    public override Material materialForRendering
    {
        get
        {
            var _material = new Material(base.materialForRendering);
            _material.SetInt("_StencilComp", (int)CompareFunction.NotEqual);
            return _material;
        }
    }
}
原因与解决方案

核心原因

异步加载场景时,Unity UI的渲染初始化流程和同步加载存在差异:

  • materialForRendering属性只有在UI元素首次准备渲染时才会被Unity读取一次
  • 异步加载完成后,这个属性的自定义逻辑没有被触发,导致Unity依旧使用默认的模板对比参数,而非你设置的NotEqual
  • 禁用再启用对象时,会强制UI元素重新走一遍渲染准备流程,这时materialForRendering的自定义逻辑才会执行,模板参数被正确设置,遮罩也就正常生效了

修复方案

方案1:主动触发渲染刷新

在异步加载场景完成的回调里,给所有CutOutImage实例调用SetAllDirty()方法,强制刷新渲染状态:

SceneManager.LoadSceneAsync("你的场景名").completed += operation =>
{
    var allCutOutImages = FindObjectsOfType<CutOutImage>();
    foreach (var img in allCutOutImages)
    {
        img.SetAllDirty();
    }
};

方案2:优化自定义类的实现

你当前的代码每次获取materialForRendering都会创建新Material,既浪费内存,也容易出现初始化时机问题。可以改成在初始化时就设置好模板参数:

public class CutOutImage : Image
{
    protected override void Awake()
    {
        base.Awake();
        // 如果是共享材质,先实例化再修改,避免影响其他UI元素
        if (material != null && material.IsSharedMaterial)
        {
            material = new Material(material);
        }
        material?.SetInt("_StencilComp", (int)CompareFunction.NotEqual);
    }

    // 保留重写以支持动态调整场景
    public override Material materialForRendering
    {
        get
        {
            var targetMat = base.materialForRendering;
            targetMat.SetInt("_StencilComp", (int)CompareFunction.NotEqual);
            return targetMat;
        }
    }
}

方案3:绑定到对象启用事件

如果不想在场景加载回调里处理,可以给CutOutImage加个事件监听,在对象启用时强制刷新:

public class CutOutImage : Image
{
    private void OnEnable()
    {
        SetAllDirty();
    }

    public override Material materialForRendering
    {
        get
        {
            var _material = new Material(base.materialForRendering);
            _material.SetInt("_StencilComp", (int)CompareFunction.NotEqual);
            return _material;
        }
    }
}

内容的提问来源于stack exchange,提问作者Kureyş Alp Kılıç

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:15:08