EnvironmentLibrary.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using UnityEngine;
  2. using UnityEngine.Rendering;
  3. using System;
  4. using System.Collections.Generic;
  5. using UnityEngine.UIElements;
  6. using System.IO;
  7. using UnityEditor.UIElements;
  8. namespace UnityEditor.Rendering.LookDev
  9. {
  10. /// <summary>
  11. /// Class containing a collection of Environment
  12. /// </summary>
  13. [HelpURL(Documentation.baseURLHDRP + Documentation.version + Documentation.subURL + "Environment-Library" + Documentation.endURL)]
  14. public class EnvironmentLibrary : ScriptableObject
  15. {
  16. [field: SerializeField]
  17. List<Environment> environments { get; set; } = new List<Environment>();
  18. /// <summary>
  19. /// Number of elements in the collection
  20. /// </summary>
  21. public int Count => environments.Count;
  22. /// <summary>
  23. /// Indexer giving access to contained Environment
  24. /// </summary>
  25. public Environment this[int index] => environments[index];
  26. /// <summary>
  27. /// Create a new empty Environment at the end of the collection
  28. /// </summary>
  29. /// <returns>The created Environment</returns>
  30. public Environment Add()
  31. {
  32. Environment environment = ScriptableObject.CreateInstance<Environment>();
  33. environment.name = "New Environment";
  34. Undo.RegisterCreatedObjectUndo(environment, "Add Environment");
  35. environments.Add(environment);
  36. // Store this new environment as a subasset so we can reference it safely afterwards.
  37. AssetDatabase.AddObjectToAsset(environment, this);
  38. // Force save / refresh. Important to do this last because SaveAssets can cause effect to become null!
  39. EditorUtility.SetDirty(this);
  40. AssetDatabase.SaveAssets();
  41. return environment;
  42. }
  43. /// <summary>
  44. /// Remove Environment of the collection at given index
  45. /// </summary>
  46. /// <param name="index">Index where to remove Environment</param>
  47. public void Remove(int index)
  48. {
  49. Environment environment = environments[index];
  50. Undo.RecordObject(this, "Remove Environment");
  51. environments.RemoveAt(index);
  52. Undo.DestroyObjectImmediate(environment);
  53. // Force save / refresh
  54. EditorUtility.SetDirty(this);
  55. AssetDatabase.SaveAssets();
  56. }
  57. /// <summary>
  58. /// Duplicate the Environment at given index and add it at the end of the Collection
  59. /// </summary>
  60. /// <param name="fromIndex">Index where to take data for duplication</param>
  61. /// <returns>The created Environment</returns>
  62. public Environment Duplicate(int fromIndex)
  63. {
  64. Environment environment = ScriptableObject.CreateInstance<Environment>();
  65. Environment environmentToCopy = environments[fromIndex];
  66. environmentToCopy.CopyTo(environment);
  67. Undo.RegisterCreatedObjectUndo(environment, "Duplicate Environment");
  68. environments.Add(environment);
  69. // Store this new environment as a subasset so we can reference it safely afterwards.
  70. AssetDatabase.AddObjectToAsset(environment, this);
  71. // Force save / refresh. Important to do this last because SaveAssets can cause effect to become null!
  72. EditorUtility.SetDirty(this);
  73. AssetDatabase.SaveAssets();
  74. return environment;
  75. }
  76. /// <summary>
  77. /// Compute position of given Environment in the collection
  78. /// </summary>
  79. /// <param name="environment">Environment to look at</param>
  80. /// <returns>Index of the searched environment. If not found, -1.</returns>
  81. public int IndexOf(Environment environment)
  82. => environments.IndexOf(environment);
  83. }
  84. [CustomEditor(typeof(EnvironmentLibrary))]
  85. class EnvironmentLibraryEditor : Editor
  86. {
  87. VisualElement root;
  88. public sealed override VisualElement CreateInspectorGUI()
  89. {
  90. var library = target as EnvironmentLibrary;
  91. root = new VisualElement();
  92. Button open = new Button(() =>
  93. {
  94. if (!LookDev.open)
  95. LookDev.Open();
  96. LookDev.currentContext.UpdateEnvironmentLibrary(library);
  97. LookDev.currentEnvironmentDisplayer.Repaint();
  98. })
  99. {
  100. text = "Open in LookDev window"
  101. };
  102. root.Add(open);
  103. return root;
  104. }
  105. // Don't use ImGUI
  106. public sealed override void OnInspectorGUI() { }
  107. }
  108. class EnvironmentLibraryCreator : ProjectWindowCallback.EndNameEditAction
  109. {
  110. ObjectField m_Field = null;
  111. public void SetField(ObjectField field)
  112. => m_Field = field;
  113. public override void Cancelled(int instanceId, string pathName, string resourceFile)
  114. => m_Field = null;
  115. public override void Action(int instanceId, string pathName, string resourceFile)
  116. {
  117. var newAsset = CreateInstance<EnvironmentLibrary>();
  118. newAsset.name = Path.GetFileName(pathName);
  119. AssetDatabase.CreateAsset(newAsset, pathName);
  120. ProjectWindowUtil.ShowCreatedAsset(newAsset);
  121. if (m_Field != null)
  122. m_Field.value = newAsset;
  123. m_Field = null;
  124. }
  125. [MenuItem("Assets/Create/LookDev/Environment Library", priority = 2000)]
  126. static void Create()
  127. {
  128. var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
  129. ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance<EnvironmentLibraryCreator>(), "New EnvironmentLibrary.asset", icon, null);
  130. }
  131. public static void CreateAndAssignTo(ObjectField field)
  132. {
  133. var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon");
  134. var assetCreator = ScriptableObject.CreateInstance<EnvironmentLibraryCreator>();
  135. assetCreator.SetField(field);
  136. ProjectWindowUtil.StartNameEditingIfProjectWindowExists(assetCreator.GetInstanceID(), assetCreator, "New EnvironmentLibrary.asset", icon, null);
  137. }
  138. }
  139. static class EnvironmentLibraryLoader
  140. {
  141. static Action<UnityEngine.Object> LoadCallback(Action onUpdate)
  142. {
  143. return (UnityEngine.Object newLibrary) =>
  144. {
  145. LookDev.currentContext.UpdateEnvironmentLibrary(newLibrary as EnvironmentLibrary);
  146. onUpdate?.Invoke();
  147. };
  148. }
  149. }
  150. }