using System; using UnityEditor; using UnityEngine.Serialization; namespace UnityEngine.Rendering.Universal { /// /// Universal Render Pipeline's Global Settings. /// Global settings are unique per Render Pipeline type. In URP, Global Settings contain: /// - light layer names /// [URPHelpURL("urp-global-settings")] [DisplayInfo(name = "URP Global Settings Asset", order = CoreUtils.Sections.section4 + 2)] [SupportedOnRenderPipeline(typeof(UniversalRenderPipelineAsset))] partial class UniversalRenderPipelineGlobalSettings : RenderPipelineGlobalSettings { #region Version system private const int k_LastVersion = 5; #pragma warning disable CS0414 [SerializeField][FormerlySerializedAs("k_AssetVersion")] int m_AssetVersion = k_LastVersion; #pragma warning restore CS0414 public void OnBeforeSerialize() { } public void OnAfterDeserialize() { #if UNITY_EDITOR if (m_AssetVersion != k_LastVersion) { EditorApplication.delayCall += () => UpgradeAsset(this.GetInstanceID()); } #endif } #if UNITY_EDITOR static void UpgradeAsset(int assetInstanceID) { if (EditorUtility.InstanceIDToObject(assetInstanceID) is not UniversalRenderPipelineGlobalSettings asset) return; int assetVersionBeforeUpgrade = asset.m_AssetVersion; if (asset.m_AssetVersion < 2) { #pragma warning disable 618 // Obsolete warning // Renamed supportRuntimeDebugDisplay => stripDebugVariants, which results in inverted logic asset.m_StripDebugVariants = !asset.supportRuntimeDebugDisplay; asset.m_AssetVersion = 2; #pragma warning restore 618 // Obsolete warning // For old test projects lets keep post processing stripping enabled, as huge chance they did not used runtime profile creating #if UNITY_INCLUDE_TESTS #pragma warning disable 618 // Obsolete warning asset.m_StripUnusedPostProcessingVariants = true; #pragma warning restore 618 // Obsolete warning #endif } if (asset.m_AssetVersion < 3) { int index = 0; asset.m_RenderingLayerNames = new string[8]; #pragma warning disable 618 // Obsolete warning asset.m_RenderingLayerNames[index++] = asset.lightLayerName0; asset.m_RenderingLayerNames[index++] = asset.lightLayerName1; asset.m_RenderingLayerNames[index++] = asset.lightLayerName2; asset.m_RenderingLayerNames[index++] = asset.lightLayerName3; asset.m_RenderingLayerNames[index++] = asset.lightLayerName4; asset.m_RenderingLayerNames[index++] = asset.lightLayerName5; asset.m_RenderingLayerNames[index++] = asset.lightLayerName6; asset.m_RenderingLayerNames[index++] = asset.lightLayerName7; #pragma warning restore 618 // Obsolete warning asset.m_AssetVersion = 3; asset.UpdateRenderingLayerNames(); } if (asset.m_AssetVersion < 4) { #pragma warning disable 618 // Type or member is obsolete asset.m_ShaderStrippingSetting.exportShaderVariants = asset.m_ExportShaderVariants; asset.m_ShaderStrippingSetting.shaderVariantLogLevel = asset.m_ShaderVariantLogLevel; asset.m_ShaderStrippingSetting.stripRuntimeDebugShaders = asset.m_StripDebugVariants; asset.m_URPShaderStrippingSetting.stripScreenCoordOverrideVariants = asset.m_StripScreenCoordOverrideVariants; asset.m_URPShaderStrippingSetting.stripUnusedPostProcessingVariants = asset.m_StripUnusedPostProcessingVariants; asset.m_URPShaderStrippingSetting.stripUnusedVariants = asset.m_StripUnusedVariants; #pragma warning restore 618 } if (asset.m_AssetVersion < 5) { asset.GetOrCreateDefaultVolumeProfile(); asset.m_AssetVersion = 5; } // If the asset version has changed, means that a migration step has been executed if (assetVersionBeforeUpgrade != asset.m_AssetVersion) EditorUtility.SetDirty(asset); } #endif #endregion /// Default name when creating an URP Global Settings asset. public const string defaultAssetName = "UniversalRenderPipelineGlobalSettings"; #if UNITY_EDITOR internal static string defaultPath => $"Assets/{defaultAssetName}.asset"; //Making sure there is at least one UniversalRenderPipelineGlobalSettings instance in the project internal static UniversalRenderPipelineGlobalSettings Ensure(bool canCreateNewAsset = true) { UniversalRenderPipelineGlobalSettings currentInstance = GraphicsSettings. GetSettingsForRenderPipeline() as UniversalRenderPipelineGlobalSettings; if (RenderPipelineGlobalSettingsUtils.TryEnsure(ref currentInstance, defaultPath, canCreateNewAsset)) { if (currentInstance != null && currentInstance.m_AssetVersion != k_LastVersion) UpgradeAsset(currentInstance.GetInstanceID()); return currentInstance; } return null; } public override void Initialize(RenderPipelineGlobalSettings source = null) { if (source is UniversalRenderPipelineGlobalSettings globalSettingsSource) Array.Copy(globalSettingsSource.m_RenderingLayerNames, m_RenderingLayerNames, globalSettingsSource.m_RenderingLayerNames.Length); GetOrCreateDefaultVolumeProfile(); } #endif void Reset() { UpdateRenderingLayerNames(); } internal VolumeProfile GetOrCreateDefaultVolumeProfile() { #if UNITY_EDITOR if (volumeProfile == null || volumeProfile.Equals(null)) { const string k_DefaultVolumeProfileName = "DefaultVolumeProfile"; const string k_DefaultVolumeProfilePath = "Assets/" + k_DefaultVolumeProfileName + ".asset"; VolumeProfile assetCreated = CreateInstance(); Debug.Assert(assetCreated); assetCreated.name = k_DefaultVolumeProfileName; AssetDatabase.CreateAsset(assetCreated, k_DefaultVolumeProfilePath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); volumeProfile = assetCreated; if (VolumeManager.instance.isInitialized) VolumeManager.instance.SetGlobalDefaultProfile(volumeProfile); } #endif return volumeProfile; } [SerializeField] private VolumeProfile m_DefaultVolumeProfile; internal VolumeProfile volumeProfile { get => m_DefaultVolumeProfile; set => m_DefaultVolumeProfile = value; } [SerializeField] string[] m_RenderingLayerNames = new string[] { "Default" }; string[] renderingLayerNames { get { if (m_RenderingLayerNames == null) UpdateRenderingLayerNames(); return m_RenderingLayerNames; } } [System.NonSerialized] string[] m_PrefixedRenderingLayerNames; string[] prefixedRenderingLayerNames { get { if (m_PrefixedRenderingLayerNames == null) UpdateRenderingLayerNames(); return m_PrefixedRenderingLayerNames; } } /// Names used for display of rendering layer masks. public string[] renderingLayerMaskNames => renderingLayerNames; /// Names used for display of rendering layer masks with a prefix. public string[] prefixedRenderingLayerMaskNames => prefixedRenderingLayerNames; [SerializeField] uint m_ValidRenderingLayers; /// Valid rendering layers that can be used by graphics. public uint validRenderingLayers => m_ValidRenderingLayers; /// Regenerate Rendering Layer names and their prefixed versions. internal void UpdateRenderingLayerNames() { // Update prefixed if (m_PrefixedRenderingLayerNames == null) m_PrefixedRenderingLayerNames = new string[32]; for (int i = 0; i < m_PrefixedRenderingLayerNames.Length; ++i) { uint renderingLayer = (uint)(1 << i); m_ValidRenderingLayers = i < m_RenderingLayerNames.Length ? (m_ValidRenderingLayers | renderingLayer) : (m_ValidRenderingLayers & ~renderingLayer); m_PrefixedRenderingLayerNames[i] = i < m_RenderingLayerNames.Length ? m_RenderingLayerNames[i] : $"Unused Layer {i}"; } // Update decals DecalProjector.UpdateAllDecalProperties(); } /// /// Names used for display of light layers with Layer's index as prefix. /// For example: "0: Light Layer Default" /// [Obsolete("This is obsolete, please use prefixedRenderingLayerMaskNames instead.", true)] public string[] prefixedLightLayerNames => new string[0]; #region Light Layer Names [3D] /// Name for light layer 0. [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string lightLayerName0; /// Name for light layer 1. [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string lightLayerName1; /// Name for light layer 2. [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string lightLayerName2; /// Name for light layer 3. [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string lightLayerName3; /// Name for light layer 4. [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string lightLayerName4; /// Name for light layer 5. [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string lightLayerName5; /// Name for light layer 6. [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string lightLayerName6; /// Name for light layer 7. [Obsolete("This is obsolete, please use renderingLayerNames instead.", false)] public string lightLayerName7; /// /// Names used for display of light layers. /// [Obsolete("This is obsolete, please use renderingLayerMaskNames instead.", false)] public string[] lightLayerNames => new string[0]; internal void ResetRenderingLayerNames() { m_RenderingLayerNames = new string[] { "Default"}; } #endregion } }