using UnityEngine; using UnityEngine.Rendering; using System; using System.Collections.Generic; using UnityEngine.UIElements; using System.IO; using UnityEditor.UIElements; namespace UnityEditor.Rendering.LookDev { /// /// Class containing a collection of Environment /// [HelpURL(Documentation.baseURLHDRP + Documentation.version + Documentation.subURL + "Environment-Library" + Documentation.endURL)] public class EnvironmentLibrary : ScriptableObject { [field: SerializeField] List environments { get; set; } = new List(); /// /// Number of elements in the collection /// public int Count => environments.Count; /// /// Indexer giving access to contained Environment /// public Environment this[int index] => environments[index]; /// /// Create a new empty Environment at the end of the collection /// /// The created Environment public Environment Add() { Environment environment = ScriptableObject.CreateInstance(); environment.name = "New Environment"; Undo.RegisterCreatedObjectUndo(environment, "Add Environment"); environments.Add(environment); // Store this new environment as a subasset so we can reference it safely afterwards. AssetDatabase.AddObjectToAsset(environment, this); // Force save / refresh. Important to do this last because SaveAssets can cause effect to become null! EditorUtility.SetDirty(this); AssetDatabase.SaveAssets(); return environment; } /// /// Remove Environment of the collection at given index /// /// Index where to remove Environment public void Remove(int index) { Environment environment = environments[index]; Undo.RecordObject(this, "Remove Environment"); environments.RemoveAt(index); Undo.DestroyObjectImmediate(environment); // Force save / refresh EditorUtility.SetDirty(this); AssetDatabase.SaveAssets(); } /// /// Duplicate the Environment at given index and add it at the end of the Collection /// /// Index where to take data for duplication /// The created Environment public Environment Duplicate(int fromIndex) { Environment environment = ScriptableObject.CreateInstance(); Environment environmentToCopy = environments[fromIndex]; environmentToCopy.CopyTo(environment); Undo.RegisterCreatedObjectUndo(environment, "Duplicate Environment"); environments.Add(environment); // Store this new environment as a subasset so we can reference it safely afterwards. AssetDatabase.AddObjectToAsset(environment, this); // Force save / refresh. Important to do this last because SaveAssets can cause effect to become null! EditorUtility.SetDirty(this); AssetDatabase.SaveAssets(); return environment; } /// /// Compute position of given Environment in the collection /// /// Environment to look at /// Index of the searched environment. If not found, -1. public int IndexOf(Environment environment) => environments.IndexOf(environment); } [CustomEditor(typeof(EnvironmentLibrary))] class EnvironmentLibraryEditor : Editor { VisualElement root; public sealed override VisualElement CreateInspectorGUI() { var library = target as EnvironmentLibrary; root = new VisualElement(); Button open = new Button(() => { if (!LookDev.open) LookDev.Open(); LookDev.currentContext.UpdateEnvironmentLibrary(library); LookDev.currentEnvironmentDisplayer.Repaint(); }) { text = "Open in LookDev window" }; root.Add(open); return root; } // Don't use ImGUI public sealed override void OnInspectorGUI() { } } class EnvironmentLibraryCreator : ProjectWindowCallback.EndNameEditAction { ObjectField m_Field = null; public void SetField(ObjectField field) => m_Field = field; public override void Cancelled(int instanceId, string pathName, string resourceFile) => m_Field = null; public override void Action(int instanceId, string pathName, string resourceFile) { var newAsset = CreateInstance(); newAsset.name = Path.GetFileName(pathName); AssetDatabase.CreateAsset(newAsset, pathName); ProjectWindowUtil.ShowCreatedAsset(newAsset); if (m_Field != null) m_Field.value = newAsset; m_Field = null; } [MenuItem("Assets/Create/LookDev/Environment Library", priority = 2000)] static void Create() { var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon"); ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance(), "New EnvironmentLibrary.asset", icon, null); } public static void CreateAndAssignTo(ObjectField field) { var icon = EditorGUIUtility.FindTexture("ScriptableObject Icon"); var assetCreator = ScriptableObject.CreateInstance(); assetCreator.SetField(field); ProjectWindowUtil.StartNameEditingIfProjectWindowExists(assetCreator.GetInstanceID(), assetCreator, "New EnvironmentLibrary.asset", icon, null); } } static class EnvironmentLibraryLoader { static Action LoadCallback(Action onUpdate) { return (UnityEngine.Object newLibrary) => { LookDev.currentContext.UpdateEnvironmentLibrary(newLibrary as EnvironmentLibrary); onUpdate?.Invoke(); }; } } }