1

如何动态获取URP设置里自定义的RenderFeatures

 2 years ago
source link: https://blog.uwa4d.com/archives/TechSharing_295.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

1)如何动态获取URP设置里自定义的RenderFeatures
​2)UGUI里,把UI丢回池里,把方案SetActive(false)方法的最佳
3)Prefab中m_Text会自动换行导致搜索不到
4)URP变体优化shader_feature,MAIN_LIGHT_SHADOWS关键字废弃


这是第295篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)

Script

Q:我们在URP项目中自定义了多个RenderFeatures去实现游戏效果,现在想动态开启和关闭相关的RenderFeatures,请问怎么在代码里动态获取这些Features呢?

A:我们使用反射获取,供参考:

public static class ScriptableRendererExtension
{
    private static readonly Dictionary<ScriptableRenderer, Dictionary<string, ScriptableRendererFeature>> s_renderFeatures = new Dictionary<ScriptableRenderer, Dictionary<string, ScriptableRendererFeature>>();

    public static ScriptableRendererFeature GetRendererFeature(this ScriptableRenderer renderer, string name)
    {
        if (!s_renderFeatures.TryGetValue(renderer, out var innerFeatures))
        {
            var propertyInfo = renderer.GetType().GetProperty("rendererFeatures", BindingFlags.Instance | BindingFlags.NonPublic);
            List<ScriptableRendererFeature> rendererFeatures = (List<ScriptableRendererFeature>)propertyInfo?.GetValue(renderer);
            if (rendererFeatures == null)
            {
                s_renderFeatures[renderer] = null;
            }
            else
            {
                innerFeatures = new Dictionary<string, ScriptableRendererFeature>();
                for (var i = 0; i < rendererFeatures.Count; i++)
                {
                    var feature = rendererFeatures[i];
                    innerFeatures[feature.name] = feature;
                }
                s_renderFeatures[renderer] = innerFeatures;
            }
        }
        if (innerFeatures != null)
        {
            innerFeatures.TryGetValue(name, out var result);
            return result;
        }
        return null;
    }
}

感谢yqsas@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/625d1d50a43e6117d06de3b8


Q:想请教下在UGUI里,把UI扔回池里,取代SetActive(false)这种低效方法的最佳方案是什么呢?具体应当怎样操作?

A1:可以尝试移到屏幕外的一个池子里,不SetActive(false),SetScale=0,Disable一些逻辑脚本,移回去的时候做相反的操作。配合一些数值初始化的操作,可以减少UI重建的耗时。

感谢小ben@UWA问答社区提供了回答

A2:可以使用Canvas Group,改变Alpha来代替SetActive(),不会触发UI重建,我们有些项目已经使用这样的方式,效果还不错。

感谢廖武兴@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/625fd559a43e6117d071a58a


Script

Q:在Prefab中的m_Text会自动换行,导致完全匹配搜索的时候搜索不到,这应该怎么解决?

A:如果使用类似文本读取的方式解析Prefab,会出现换行的问题。

可以考虑使用AssetDatabase.LoadAssetAtPath来提取所有文本:

string[] dirs = { “Assets” };
var asstIds = AssetDatabase.FindAssets(“t:Prefab”, dirs);
for (int i = 0; i < asstIds.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(asstIds[i]);
var obj = AssetDatabase.LoadAssetAtPath(path);
var text = obj.GetComponent();
Debug.Log(text.text);
}

感谢萧小俊@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/626127e436a2fd066de2f74f


Shader

Q:为了优化变体数量,将URP Shader中的multi_compile改成了shader_feature,然后遍历所有场景角色,收集一个变体和所有Shader打在了一个AssetBundle中。结果就是PC包的变体正常,但是Android包的变体却丢失了部分Keywords,主要是这个_MAIN_LIGHT_SHADOWS。

PC包:

1.png

Android包:

2.png

上面所有的关键字都是shader_feature定义的,但是只丢失_MAIN_LIGHT_SHADOWS和_MAIN_LIGHT_SHADOWS_CASCADE。

然后通过AssetStudio排查在shader.ab内编译后的Shader文件,也能够找到这个变体,说明这个变体实际上是在包内的。

3.png

再测试将Shader中的shader_feature还原成multi_compile形式,Android包的变体显示也都正确了,跟PC一样。

大家有遇到过类似的URP管线丢变体问题么?

A:找到原因了,遍历场景收集变体的代码写的有点问题,收集的时候Editor是PC平台,只考虑了开启阴影+Cascade的时候的变体。

所以PC上同时存在_MAIN_LIGHT_SHADOWS和_MAIN_LIGHT_SHADOWS_CASCADE关键字,表现是正常的。

而Android机器上没开启级联阴影,所以只有这个关键字_MAIN_LIGHT_SHADOWS,其实变体没有收集到。

感谢题主范世青@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/625e6f91a43e6117d06fab82

封面图来源于网络


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859(原群已满员)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK