A game about forced loneliness, made by TACStudios
at master 209 lines 7.9 kB view raw
1using UnityEngine; 2using UnityEngine.Rendering; 3using System; 4using System.Collections.Generic; 5using UnityEngine.UIElements; 6using System.IO; 7using UnityEditor; 8using UnityEditor.UIElements; 9 10namespace UnityEditor.Rendering.LookDev 11{ 12 /// <summary> 13 /// Class containing a collection of Environment 14 /// </summary> 15 [CoreRPHelpURL("Environment-Library")] 16 public class EnvironmentLibrary : ScriptableObject 17 { 18 [field: SerializeField] 19 List<Environment> environments { get; set; } = new List<Environment>(); 20 21 /// <summary> 22 /// Number of elements in the collection 23 /// </summary> 24 public int Count => environments.Count; 25 /// <summary> 26 /// Indexer giving access to contained Environment 27 /// </summary> 28 /// <param name="index">The zero-based index of the environment to retrieve.</param> 29 /// <value>The Environment object at the specified index.</value> 30 public Environment this[int index] => environments[index]; 31 32 /// <summary> 33 /// Create a new empty Environment at the end of the collection 34 /// </summary> 35 /// <returns>The created Environment</returns> 36 public Environment Add() 37 { 38 Undo.SetCurrentGroupName("Add Environment"); 39 int group = Undo.GetCurrentGroup(); 40 41 Environment environment = ScriptableObject.CreateInstance<Environment>(); 42 environment.name = "New Environment"; 43 Undo.RegisterCreatedObjectUndo(environment, "Add Environment"); 44 45 Undo.RecordObject(this, "Add Environment"); 46 environments.Add(environment); 47 48 // Store this new environment as a subasset so we can reference it safely afterwards. 49 AssetDatabase.AddObjectToAsset(environment, this); 50 51 Undo.CollapseUndoOperations(group); 52 53 // Force save / refresh. Important to do this last because SaveAssets can cause effect to become null! 54 EditorUtility.SetDirty(this); 55 AssetDatabase.SaveAssets(); 56 57 return environment; 58 } 59 60 /// <summary> 61 /// Remove Environment of the collection at given index 62 /// </summary> 63 /// <param name="index">Index where to remove Environment</param> 64 public void Remove(int index) 65 { 66 Undo.SetCurrentGroupName("Remove Environment"); 67 int group = Undo.GetCurrentGroup(); 68 69 Environment environment = environments[index]; 70 Undo.RecordObject(this, "Remove Environment"); 71 environments.RemoveAt(index); 72 Undo.DestroyObjectImmediate(environment); 73 74 Undo.CollapseUndoOperations(group); 75 76 // Force save / refresh 77 EditorUtility.SetDirty(this); 78 AssetDatabase.SaveAssets(); 79 } 80 81 /// <summary> 82 /// Duplicate the Environment at given index and add it at the end of the Collection 83 /// </summary> 84 /// <param name="fromIndex">Index where to take data for duplication</param> 85 /// <returns>The created Environment</returns> 86 public Environment Duplicate(int fromIndex) 87 { 88 Undo.SetCurrentGroupName("Duplicate Environment"); 89 int group = Undo.GetCurrentGroup(); 90 91 Environment environment = ScriptableObject.CreateInstance<Environment>(); 92 Environment environmentToCopy = environments[fromIndex]; 93 environmentToCopy.CopyTo(environment); 94 95 Undo.RegisterCreatedObjectUndo(environment, "Duplicate Environment"); 96 Undo.RecordObject(this, "Duplicate Environment"); 97 environments.Add(environment); 98 99 // Store this new environment as a subasset so we can reference it safely afterwards. 100 AssetDatabase.AddObjectToAsset(environment, this); 101 102 Undo.CollapseUndoOperations(group); 103 104 // Force save / refresh. Important to do this last because SaveAssets can cause effect to become null! 105 EditorUtility.SetDirty(this); 106 AssetDatabase.SaveAssets(); 107 108 return environment; 109 } 110 111 /// <summary> 112 /// Compute position of given Environment in the collection 113 /// </summary> 114 /// <param name="environment">Environment to look at</param> 115 /// <returns>Index of the searched environment. If not found, -1.</returns> 116 public int IndexOf(Environment environment) 117 => environments.IndexOf(environment); 118 } 119 120 [CustomEditor(typeof(EnvironmentLibrary))] 121 class EnvironmentLibraryEditor : Editor 122 { 123 VisualElement m_Root; 124 VisualElement m_OpenButton; 125 126 public sealed override VisualElement CreateInspectorGUI() 127 { 128 var library = target as EnvironmentLibrary; 129 m_Root = new VisualElement(); 130 131 m_OpenButton = new Button(() => 132 { 133 if (!LookDev.open) 134 LookDev.Open(); 135 LookDev.currentContext.UpdateEnvironmentLibrary(library); 136 LookDev.currentEnvironmentDisplayer.Repaint(); 137 }) 138 { 139 text = "Open in Look Dev window" 140 }; 141 m_OpenButton.SetEnabled(LookDev.supported); 142 143 m_Root.Add(m_OpenButton); 144 return m_Root; 145 } 146 147 void OnEnable() => EditorApplication.update += Update; 148 void OnDisable() => EditorApplication.update -= Update; 149 150 void Update() 151 { 152 // Current SRP can be changed at any time so we need to do this at every update. 153 if (m_OpenButton != null) 154 m_OpenButton.SetEnabled(LookDev.supported); 155 } 156 157 // Don't use ImGUI 158 public sealed override void OnInspectorGUI() { } 159 } 160 161 class EnvironmentLibraryCreator : ProjectWindowCallback.EndNameEditAction 162 { 163 ObjectField m_Field = null; 164 165 public void SetField(ObjectField field) 166 => m_Field = field; 167 168 public override void Cancelled(int instanceId, string pathName, string resourceFile) 169 => m_Field = null; 170 171 public override void Action(int instanceId, string pathName, string resourceFile) 172 { 173 var newAsset = CreateInstance<EnvironmentLibrary>(); 174 newAsset.name = Path.GetFileName(pathName); 175 AssetDatabase.CreateAsset(newAsset, pathName); 176 ProjectWindowUtil.ShowCreatedAsset(newAsset); 177 if (m_Field != null) 178 m_Field.value = newAsset; 179 m_Field = null; 180 } 181 182 [MenuItem("Assets/Create/Rendering/Environment Library (Look Dev)", priority = CoreUtils.Sections.section8 + CoreUtils.Priorities.assetsCreateRenderingMenuPriority)] 183 static void Create() 184 { 185 var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon"); 186 ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<EnvironmentLibraryCreator>(), "New EnvironmentLibrary.asset", icon, null); 187 } 188 189 public static void CreateAndAssignTo(ObjectField field) 190 { 191 var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon"); 192 var assetCreator = ScriptableObject.CreateInstance<EnvironmentLibraryCreator>(); 193 assetCreator.SetField(field); 194 ProjectWindowUtil.StartNameEditingIfProjectWindowExists(assetCreator.GetInstanceID(), assetCreator, "New EnvironmentLibrary.asset", icon, null); 195 } 196 } 197 198 static class EnvironmentLibraryLoader 199 { 200 static Action<UnityEngine.Object> LoadCallback(Action onUpdate) 201 { 202 return (UnityEngine.Object newLibrary) => 203 { 204 LookDev.currentContext.UpdateEnvironmentLibrary(newLibrary as EnvironmentLibrary); 205 onUpdate?.Invoke(); 206 }; 207 } 208 } 209}