#if UNITY_EDITOR using System; using System.Linq; using System.Reflection; using UnityEditor; using UnityEditor.Rendering; namespace UnityEngine.Rendering { /// /// Set of utilities for /// public class RenderPipelineGlobalSettingsUtils { /// /// Creates a asset /// /// The path where Unity generates the asset. /// Another `RenderPipelineGlobalSettings` that Unity uses as a data source. /// /// Returns the asset created. public static TGlobalSetting Create(string path, TGlobalSetting dataSource = null) where TGlobalSetting : RenderPipelineGlobalSettings { return Create(typeof(TGlobalSetting), path, dataSource) as TGlobalSetting; } /// /// Creates a asset /// /// /// The path where Unity generates the asset. /// Another `RenderPipelineGlobalSettings` that Unity uses as a data source. /// Returns the asset created. public static RenderPipelineGlobalSettings Create(Type renderPipelineGlobalSettingsType, string path, RenderPipelineGlobalSettings dataSource = null) { if (!typeof(RenderPipelineGlobalSettings).IsAssignableFrom(renderPipelineGlobalSettingsType)) throw new ArgumentException( $"{nameof(renderPipelineGlobalSettingsType)} must be a valid {typeof(RenderPipelineGlobalSettings)}"); // Sanitize the path if (string.IsNullOrEmpty(path)) path = $"Assets/{renderPipelineGlobalSettingsType.Name}.asset"; if (!path.StartsWith("assets/", StringComparison.CurrentCultureIgnoreCase)) path = $"Assets/{path}"; CoreUtils.EnsureFolderTreeInAssetFilePath(path); path = AssetDatabase.GenerateUniqueAssetPath(path); var assetCreated = ScriptableObject.CreateInstance(renderPipelineGlobalSettingsType) as RenderPipelineGlobalSettings; if (assetCreated != null) { AssetDatabase.CreateAsset(assetCreated, path); // copy data from provided source if (dataSource != null) EditorUtility.CopySerializedManagedFieldsOnly(dataSource, assetCreated); EditorGraphicsSettings.PopulateRenderPipelineGraphicsSettings(assetCreated); assetCreated.Initialize(dataSource); EditorUtility.SetDirty(assetCreated); AssetDatabase.SaveAssetIfDirty(assetCreated); AssetDatabase.Refresh(); } return assetCreated; } /// /// Checks that a asset exists. /// If the asset isn't valid, Unity tries the following in order: /// 1. Loads the asset at the default path. /// 2. Finds any asset in the project with the same type. /// 3. If `canCreateNewAsset` is true, creates a new asset in the default path. /// If Unity finds or creates a valid asset, Unity updates the with it. Otherwise Unity will unregister the settings for the given pipeline. /// /// The current instance of the asset. /// The default path. /// If set to `true`, Unity creates a new asset if it can't find an existing asset in the project. /// The type of global settings asset to check. /// The type of `RenderPipeline` that this asset belongs to. /// The asset that Unity found or created, or `null` if Unity can't find or create a valid asset. public static bool TryEnsure(ref TGlobalSetting instance, string defaultPath = "", bool canCreateNewAsset = true) where TGlobalSetting : RenderPipelineGlobalSettings where TRenderPipeline : RenderPipeline { if (!TryEnsure(ref instance, defaultPath, canCreateNewAsset, out var error)) { Debug.LogError(error.Message); return false; } return true; } // This method is exposed to Unit Tests internal static bool TryEnsure(ref TGlobalSetting instance, string defaultPath, bool canCreateNewAsset, out Exception error) where TGlobalSetting : RenderPipelineGlobalSettings where TRenderPipeline : RenderPipeline { var globalSettingsName = typeof(TGlobalSetting).GetCustomAttribute()?.name ?? typeof(TGlobalSetting).Name; if (instance == null || instance.Equals(null)) { if (!string.IsNullOrEmpty(defaultPath)) { // Look at default path, if the asset exist, is the one that we need instance = AssetDatabase.LoadAssetAtPath(defaultPath); } if (instance == null) { // There was not saved into the default path, fetch the asset database to see if there is one defined in the project instance = CoreUtils.LoadAllAssets().FirstOrDefault(); if (instance == null) { // Try to create one if possible if (canCreateNewAsset) { instance = Create(defaultPath); if (instance != null) { Debug.LogWarning($"{globalSettingsName} has been created for you. If you want to modify it, go to Project Settings > Graphics > {globalSettingsName}"); } } } } } error = instance == null || instance.Equals(null) ? new Exception( $"Unable to find or create a {globalSettingsName}. The configured Render Pipeline may not work correctly. Go to Project Settings > Graphics > {globalSettingsName} for additional help.") : null; EditorGraphicsSettings.SetRenderPipelineGlobalSettingsAsset(instance); return error == null; } } } #endif