用脚本添加URP的RendererData

最近遇到了一些比较奇怪的问题。

在Unity的渲染管线中,需要给URP的RenderPipeline Asset中增加一些RenderererData,这也是自定义Render Feature并且渲染的方式。具体的实现方法也很简单,准备好RendererData后,只需要再Unity的UI上点击加号就行。如下图所示:

但是实际上总是有这样那样的需求。此次需要通过脚本来动态添加这个Renderer List。 我们通过URP的源码中可以看到,这个变量不可访问,也没有对应的方法。

讲道理这样的接口应该由URP自己暴露出来,但是实际上并没有。不过既然是可序列化的变量,大概率是能够通过合法的方式操作的,但是并不打算让你访问,所以这边只能够通过反射的方式来添加了。 

直接上代码:

var proInfo = typeof(UniversalRenderPipelineAsset).GetField("m_RendererDataList",
                    BindingFlags.NonPublic | BindingFlags.Instance);

if (proInfo != null)
{
     rendererDataList = (ScriptableRendererData[])proInfo.GetValue(UniversalRenderPipeline.asset);
                
      var newList = new ScriptableRendererData[rendererDataList.Length+1];
      for (int i = 0; i < rendererDataList.Length; i++)
      {
            
            newList[i] = rendererDataList[i];
            newList[rendererDataList.Length] = newRendererData;
      }
      proInfo.SetValue(GraphicsSettings.currentRenderPipeline, newList);
}

首先先通过反射获取到对应的Field,然后强制转化为对应的rendererDataList,这时候就能够获取整个列表了。

但是这里有个问题,如果我们直接修改了List,实际上是不会生效的,因为此时的rendererDataList只是我们的一个变量,指向的位置才是真正的列表,如果我们直接:

rendererDataList = new ScriptableRendererData[10];

这样的话相当于是重新new了一个变量,是无法改变PipeLine Asset里面的列表。因此,此处还需要使用SetValue方法把新的值放回才能生效。

于是,在代码里的方法就是new一个ScriptableRendererData数组,先把获取到的列表内容塞进去,再把自定义的RendererData放到最后。再用SetValue方法来更新对应的asset。 

实测在Editor和Runtime中都能够生效。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值