#if ENABLE_UPSCALER_FRAMEWORK using System; using System.Collections.Generic; using System.Reflection; using UnityEditor; using UnityEngine.Scripting; using static UnityEngine.Rendering.DynamicResolutionHandler; namespace UnityEngine.Rendering { #nullable enable [Serializable] public class UpscalerOptions : ScriptableObject { public string UpscalerName { get => m_UpscalerName; set => m_UpscalerName = value; } public UpsamplerScheduleType InjectionPoint { get => m_InjectionPoint; set => m_InjectionPoint = value; } [SerializeField, HideInInspector] private string m_UpscalerName = ""; [SerializeField, HideInInspector] // hide in inspector for URP, HDRP manually renders it private UpsamplerScheduleType m_InjectionPoint = UpsamplerScheduleType.BeforePost; #if UNITY_EDITOR // The core method to ensure options exist and are linked. // It operates on a SerializedProperty representing the list. public static bool ValidateSerializedUpscalerOptionReferencesWithinRPAsset(ScriptableObject parentRPAsset, SerializedProperty optionsListProp) { if (parentRPAsset == null) { Debug.LogError("[Auto-Populate] Parent asset is null."); return false; } if (optionsListProp == null || !optionsListProp.isArray) { Debug.LogError($"[Auto-Populate] Provided SerializedProperty '{optionsListProp?.name ?? "null"}' is not a valid list for upscaler options."); return false; } bool propertyModified = false; // remove null entries for (int i = optionsListProp.arraySize - 1; i >= 0; i--) { SerializedProperty elementProp = optionsListProp.GetArrayElementAtIndex(i); if (elementProp.objectReferenceValue == null) { optionsListProp.DeleteArrayElementAtIndex(i); propertyModified = true; Debug.LogWarning($"[RP Asset] Removed null upscaler option from asset '{parentRPAsset.name}'."); } } // default-initialize registered upscaler options if they're not found within serialized asset foreach (var kvp in UpscalerRegistry.s_RegisteredUpscalers) { Type upscalerType = kvp.Key; Type? optionsType = kvp.Value.OptionsType; if (optionsType == null) continue; string upscalerName = kvp.Value.ID; bool foundExisting = false; for (int i = 0; i < optionsListProp.arraySize; i++) { SerializedProperty elementProp = optionsListProp.GetArrayElementAtIndex(i); UpscalerOptions? existingOption = elementProp.objectReferenceValue as UpscalerOptions; if (existingOption != null && existingOption.GetType() == optionsType /*&& existingOption.UpscalerName == upscalerName*/) { foundExisting = true; break; } } if (!foundExisting) { UpscalerOptions newOption = (UpscalerOptions)ScriptableObject.CreateInstance(optionsType); newOption.hideFlags = HideFlags.HideInHierarchy; newOption.UpscalerName = upscalerName; AssetDatabase.AddObjectToAsset(newOption, parentRPAsset); optionsListProp.arraySize++; optionsListProp.GetArrayElementAtIndex(optionsListProp.arraySize - 1).objectReferenceValue = newOption; propertyModified = true; Debug.Log($"[RP Asset] Auto-populated missing upscaler option on asset '{parentRPAsset.name}': {optionsType.Name} for ID: {upscalerName}"); } } return propertyModified; } #endif } #nullable disable } #endif // ENABLE_UPSCALER_FRAMEWORK