现在对我的项目进行安卓端发布,需要切换品质和一些Feature开关。
我是这样做的。
划分品质
首先Renerer分为2个Android和PC,图中其他不用参考。
每个副本的URP Asset分为pc和android,例如图中的
hall和hall_android。
我们可以看到hall用的pc的renderer,hall_android用的是android的renderer设置。
进入副本切换
public void SetQuality(string scenename)
{
#if UNITY_ANDROID
scenename += "_android";
#endif
if (TryGetValue(scenename, out var rpa))
{
Debug.Log("切换品质:" + scenename);
QualitySettings.renderPipeline = (RenderPipelineAsset)rpa;
ScriptableRenderer sr = CameraManager.inst.cameraData.scriptableRenderer;//
var property = typeof(ScriptableRenderer).GetProperty("rendererFeatures", BindingFlags.NonPublic | BindingFlags.Instance);
List<ScriptableRendererFeature> features = property.GetValue(sr) as List<ScriptableRendererFeature>;
for (int i = 0; i < features.Count; i++)
{
Debug.Log("features :" + features[i].name + " , active :" + features[i].isActive);
}
}
else
{
Debug.LogError("没找到这个品质:" + scenename);
}
}
TryGetValue是从所有的URPAsset里获取对应的设置,然后通过QualitySettings.renderPipeline函数覆盖设置。
后面是输出所有的features名字和开关。
开启和关闭Feature
public void EnableFeature(string featureName,bool featureEnable)
{
ScriptableRenderer sr = CameraManager.inst.cameraData.scriptableRenderer;//
var property = typeof(ScriptableRenderer).GetProperty("rendererFeatures", BindingFlags.NonPublic | BindingFlags.Instance);
List<ScriptableRendererFeature> features = property.GetValue(sr) as List<ScriptableRendererFeature>;
for (int i = 0; i < features.Count; i++)
{
if (features[i].name == featureName)
{
features[i].SetActive(featureEnable);
Debug.Log("features change :" + features[i].name + " , active :" + features[i].isActive);
}
}
}
这个接口用于开关某些feature。
特别重要的性能问题
这里要注意,因为每个副本的renderer是共用的,所以feature需要根据每个副本不同来开启关闭比较灵活。
举例说明
这里这个VolumetricLightsDepthPrePassFeature是一个雾效,如果在hall副本的时候开启了,在其他副本没有使用,那么开着就白白的浪费了性能,所以我都是默认关闭的,在副本特定位置打开,在离开副本关闭掉。
那就到这里了。
如果对你有用,请点赞。
参考