From c61f4b05ce4cf8333ccc94c0d36ca4ec24a2114e Mon Sep 17 00:00:00 2001 From: Zach Vinless Date: Sat, 12 Nov 2016 11:20:54 -0800 Subject: [PATCH] EditorResources now uses SerializedObject to maintain asset references --- .../FungusEditorResources.asset | 59 ++++++ .../FungusEditorResources.asset.meta | 8 + .../Scripts/Editor/FungusEditorResources.cs | 171 +++++++++++++----- .../Editor/FungusEditorResourcesGenerated.cs | 64 ++++--- 4 files changed, 222 insertions(+), 80 deletions(-) create mode 100644 Assets/Fungus/EditorResources/FungusEditorResources.asset create mode 100644 Assets/Fungus/EditorResources/FungusEditorResources.asset.meta diff --git a/Assets/Fungus/EditorResources/FungusEditorResources.asset b/Assets/Fungus/EditorResources/FungusEditorResources.asset new file mode 100644 index 00000000..f8d40f35 --- /dev/null +++ b/Assets/Fungus/EditorResources/FungusEditorResources.asset @@ -0,0 +1,59 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_PrefabParentObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d2af387304e4b454b9ce8b815799cad0, type: 3} + m_Name: FungusEditorResources + m_EditorClassIdentifier: + updateOnReloadScripts: 0 + add: + free: {fileID: 2800000, guid: 24a867d6b4cdda04cb3aa3350f9ec7d0, type: 3} + pro: {fileID: 2800000, guid: 4e43c476b4a7a49a08c37378fb01ce99, type: 3} + add_small: + free: {fileID: 2800000, guid: 288aff1a0e5c14fd3a0039d24149df73, type: 3} + pro: {fileID: 2800000, guid: 64534dfaa17844231a9a9dd2df89d0db, type: 3} + delete: + free: {fileID: 2800000, guid: d6fc8a97e8a5b0947a49b780f787e504, type: 3} + pro: {fileID: 2800000, guid: 29c4d29b1678042a5b3516c732ccc507, type: 3} + down: + free: {fileID: 2800000, guid: 51a973f446c2e664582861480cce6215, type: 3} + pro: {fileID: 2800000, guid: 5a87a7d3683164a238377d948572805f, type: 3} + duplicate: + free: {fileID: 2800000, guid: c97f334c466215a4f93eff31de3c1591, type: 3} + pro: {fileID: 2800000, guid: 2f17490d993c84bd7872ef6588ffba47, type: 3} + up: + free: {fileID: 2800000, guid: 8f1242ad894201f43b2b6d52fd990f77, type: 3} + pro: {fileID: 2800000, guid: 2a76a781db2994b33b83cd84b8835da7, type: 3} + choice_node_off: + free: {fileID: 2800000, guid: 7b6fc04aac74540e39e9502da5312ce7, type: 3} + pro: {fileID: 0} + choice_node_on: + free: {fileID: 2800000, guid: cfc05494b71a0446182868aab5f7febf, type: 3} + pro: {fileID: 0} + command_background: + free: {fileID: 2800000, guid: a5c9a4271b3de4e4f86eff7f8a1bd768, type: 3} + pro: {fileID: 0} + event_node_off: + free: {fileID: 2800000, guid: 0e16a209826864df7b05f6d3901aae7a, type: 3} + pro: {fileID: 0} + event_node_on: + free: {fileID: 2800000, guid: 9434488a4efb54da5986eba5d5619baf, type: 3} + pro: {fileID: 0} + play_big: + free: {fileID: 2800000, guid: bff2ba39f5f4448589e80522ebfcd0a0, type: 3} + pro: {fileID: 0} + play_small: + free: {fileID: 2800000, guid: a48a2b9b06deb469d9da1777b094521b, type: 3} + pro: {fileID: 0} + process_node_off: + free: {fileID: 2800000, guid: ea3a4228e6c214149bfe5c741b56ae0c, type: 3} + pro: {fileID: 0} + process_node_on: + free: {fileID: 2800000, guid: c2dceb780784240ccbe8d3cde89f7671, type: 3} + pro: {fileID: 0} diff --git a/Assets/Fungus/EditorResources/FungusEditorResources.asset.meta b/Assets/Fungus/EditorResources/FungusEditorResources.asset.meta new file mode 100644 index 00000000..c92acc45 --- /dev/null +++ b/Assets/Fungus/EditorResources/FungusEditorResources.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 29cae11326cb84802b83fc3ff25a47e8 +timeCreated: 1478978272 +licenseType: Free +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs b/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs index a3c9f948..109c3dda 100644 --- a/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs +++ b/Assets/Fungus/Scripts/Editor/FungusEditorResources.cs @@ -3,6 +3,7 @@ using UnityEngine; using UnityEditor; +using UnityEditor.Callbacks; using System; using System.IO; using System.Linq; @@ -10,58 +11,102 @@ using System.Collections.Generic; namespace Fungus.EditorUtils { - internal static partial class FungusEditorResources + [CustomEditor(typeof(FungusEditorResources))] + internal class FungusEditorResourcesInspector : Editor { - private static Dictionary textures = new Dictionary(); - private static readonly string editorResourcesFolderName = "\"EditorResources\""; - - static FungusEditorResources() + public override void OnInspectorGUI() { - LoadTexturesFromNames(); + if (serializedObject.FindProperty("updateOnReloadScripts").boolValue) + { + GUILayout.Label("Updating..."); + } + else + { + if (GUILayout.Button("Sync with EditorResources folder")) + { + FungusEditorResources.GenerateResourcesScript(); + } + + DrawDefaultInspector(); + } } + } - private static void LoadTexturesFromNames() + internal partial class FungusEditorResources : ScriptableObject + { + [Serializable] + internal class EditorTexture { - var baseDirectories = AssetDatabase.FindAssets(editorResourcesFolderName).Select( - guid => AssetDatabase.GUIDToAssetPath(guid) - ).ToArray(); - - foreach (var name in resourceNames) + [SerializeField] private Texture2D free; + [SerializeField] private Texture2D pro; + + public Texture2D Texture2D { - LoadTexturesFromGUIDs(AssetDatabase.FindAssets(name + " t:Texture2D", baseDirectories)); + get { return EditorGUIUtility.isProSkin && pro != null ? pro : free; } } - } - private static void LoadAllTexturesInFolder() - { - var rootGuid = AssetDatabase.FindAssets(editorResourcesFolderName)[0]; - var root = AssetDatabase.GUIDToAssetPath(rootGuid); - LoadTexturesFromGUIDs(AssetDatabase.FindAssets("t:Texture2D", new [] { root })); + public EditorTexture(Texture2D free, Texture2D pro) + { + this.free = free; + this.pro = pro; + } } - private static void LoadTexturesFromGUIDs(string[] guids) + private static FungusEditorResources instance; + private static readonly string editorResourcesFolderName = "\"EditorResources\""; + [SerializeField] [HideInInspector] private bool updateOnReloadScripts = false; + + internal static FungusEditorResources Instance { - var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).OrderBy(path => path.ToLower().Contains("/pro/")); - - foreach (var path in paths) + get { - if (path.ToLower().Contains("/pro/") && !EditorGUIUtility.isProSkin) + if (instance == null) { - return; + var guids = AssetDatabase.FindAssets("FungusEditorResources t:FungusEditorResources"); + + if (guids.Length == 0) + { + instance = ScriptableObject.CreateInstance(typeof(FungusEditorResources)) as FungusEditorResources; + AssetDatabase.CreateAsset(instance, GetRootFolder() + "/FungusEditorResources.asset"); + UpdateTextureReferences(instance); + AssetDatabase.SaveAssets(); + } + else + { + if (guids.Length > 1) + { + Debug.LogWarning("Multiple FungusEditorResources assets found!"); + } + + var path = AssetDatabase.GUIDToAssetPath(guids[0]); + instance = AssetDatabase.LoadAssetAtPath(path, typeof(FungusEditorResources)) as FungusEditorResources; + } } - var texture = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D; - textures[texture.name] = texture; + + return instance; } } - [MenuItem("Tools/Fungus/Utilities/Update Editor Resources Script")] - private static void GenerateResourcesScript() + private static string GetRootFolder() { - textures.Clear(); - LoadAllTexturesInFolder(); + var rootGuid = AssetDatabase.FindAssets(editorResourcesFolderName)[0]; + return AssetDatabase.GUIDToAssetPath(rootGuid); + } - var guid = AssetDatabase.FindAssets("FungusEditorResources t:MonoScript")[0]; - var relativePath = AssetDatabase.GUIDToAssetPath(guid).Replace("FungusEditorResources.cs", "FungusEditorResourcesGenerated.cs"); + internal static void GenerateResourcesScript() + { + // Get all unique filenames + var textureNames = new HashSet(); + var guids = AssetDatabase.FindAssets("t:Texture2D", new [] { GetRootFolder() }); + var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)); + + foreach (var path in paths) + { + textureNames.Add(Path.GetFileNameWithoutExtension(path)); + } + + var scriptGuid = AssetDatabase.FindAssets("FungusEditorResources t:MonoScript")[0]; + var relativePath = AssetDatabase.GUIDToAssetPath(scriptGuid).Replace("FungusEditorResources.cs", "FungusEditorResourcesGenerated.cs"); var absolutePath = Application.dataPath + relativePath.Substring("Assets".Length); using (var writer = new StreamWriter(absolutePath)) @@ -73,43 +118,75 @@ namespace Fungus.EditorUtils writer.WriteLine(""); writer.WriteLine("namespace Fungus.EditorUtils"); writer.WriteLine("{"); - writer.WriteLine(" internal static partial class FungusEditorResources"); + writer.WriteLine(" internal partial class FungusEditorResources : ScriptableObject"); writer.WriteLine(" {"); - writer.WriteLine(" private static readonly string[] resourceNames = new [] {"); - foreach (var pair in textures) + foreach (var name in textureNames) { - writer.WriteLine(" \"" + pair.Key + "\","); + writer.WriteLine(" [SerializeField] private EditorTexture " + name + ";"); } - writer.WriteLine(" };"); writer.WriteLine(""); - foreach (var pair in textures) + foreach (var name in textureNames) { - var name = pair.Key; var pascalCase = string.Join("", name.Split(new [] { '_' }, StringSplitOptions.RemoveEmptyEntries).Select( s => s.Substring(0, 1).ToUpper() + s.Substring(1)).ToArray() ); - writer.WriteLine(" public static Texture2D " + pascalCase + " { get { return GetTexture(\"" + name + "\"); } }"); + writer.WriteLine(" public static Texture2D " + pascalCase + " { get { return Instance." + name + ".Texture2D; } }"); } writer.WriteLine(" }"); writer.WriteLine("}"); } + Instance.updateOnReloadScripts = true; AssetDatabase.ImportAsset(relativePath); } - private static Texture2D GetTexture(string name) + [DidReloadScripts] + private static void OnDidReloadScripts() { - Texture2D texture; - if (!textures.TryGetValue(name, out texture)) + if (Instance.updateOnReloadScripts) + { + UpdateTextureReferences(Instance); + } + } + + private static void UpdateTextureReferences(FungusEditorResources instance) + { + // Iterate through all fields in class and set texture references + var serializedObject = new SerializedObject(instance); + var prop = serializedObject.GetIterator(); + var rootFolder = new [] { GetRootFolder() }; + + prop.NextVisible(true); + while (prop.NextVisible(false)) { - Debug.LogWarning("Texture \"" + name + "\" not found!"); + if (prop.propertyType == SerializedPropertyType.Generic) + { + var guids = AssetDatabase.FindAssets(prop.name + " t:Texture2D", rootFolder); + var paths = guids.Select(guid => AssetDatabase.GUIDToAssetPath(guid)).Where( + path => path.Contains(prop.name + ".") + ); + + foreach (var path in paths) + { + var texture = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D; + if (path.ToLower().Contains("/pro/")) + { + prop.FindPropertyRelative("pro").objectReferenceValue = texture; + } + else + { + prop.FindPropertyRelative("free").objectReferenceValue = texture; + } + } + } } - - return texture; + + instance.updateOnReloadScripts = false; + serializedObject.ApplyModifiedPropertiesWithoutUndo(); } } } diff --git a/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs b/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs index e2eab920..27b06e77 100644 --- a/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs +++ b/Assets/Fungus/Scripts/Editor/FungusEditorResourcesGenerated.cs @@ -5,40 +5,38 @@ using UnityEngine; namespace Fungus.EditorUtils { - internal static partial class FungusEditorResources + internal partial class FungusEditorResources : ScriptableObject { - private static readonly string[] resourceNames = new [] { - "add", - "add_small", - "delete", - "down", - "duplicate", - "up", - "choice_node_off", - "choice_node_on", - "command_background", - "event_node_off", - "event_node_on", - "play_big", - "play_small", - "process_node_off", - "process_node_on", - }; + [SerializeField] private EditorTexture add; + [SerializeField] private EditorTexture add_small; + [SerializeField] private EditorTexture delete; + [SerializeField] private EditorTexture down; + [SerializeField] private EditorTexture duplicate; + [SerializeField] private EditorTexture up; + [SerializeField] private EditorTexture choice_node_off; + [SerializeField] private EditorTexture choice_node_on; + [SerializeField] private EditorTexture command_background; + [SerializeField] private EditorTexture event_node_off; + [SerializeField] private EditorTexture event_node_on; + [SerializeField] private EditorTexture play_big; + [SerializeField] private EditorTexture play_small; + [SerializeField] private EditorTexture process_node_off; + [SerializeField] private EditorTexture process_node_on; - public static Texture2D Add { get { return GetTexture("add"); } } - public static Texture2D AddSmall { get { return GetTexture("add_small"); } } - public static Texture2D Delete { get { return GetTexture("delete"); } } - public static Texture2D Down { get { return GetTexture("down"); } } - public static Texture2D Duplicate { get { return GetTexture("duplicate"); } } - public static Texture2D Up { get { return GetTexture("up"); } } - public static Texture2D ChoiceNodeOff { get { return GetTexture("choice_node_off"); } } - public static Texture2D ChoiceNodeOn { get { return GetTexture("choice_node_on"); } } - public static Texture2D CommandBackground { get { return GetTexture("command_background"); } } - public static Texture2D EventNodeOff { get { return GetTexture("event_node_off"); } } - public static Texture2D EventNodeOn { get { return GetTexture("event_node_on"); } } - public static Texture2D PlayBig { get { return GetTexture("play_big"); } } - public static Texture2D PlaySmall { get { return GetTexture("play_small"); } } - public static Texture2D ProcessNodeOff { get { return GetTexture("process_node_off"); } } - public static Texture2D ProcessNodeOn { get { return GetTexture("process_node_on"); } } + public static Texture2D Add { get { return Instance.add.Texture2D; } } + public static Texture2D AddSmall { get { return Instance.add_small.Texture2D; } } + public static Texture2D Delete { get { return Instance.delete.Texture2D; } } + public static Texture2D Down { get { return Instance.down.Texture2D; } } + public static Texture2D Duplicate { get { return Instance.duplicate.Texture2D; } } + public static Texture2D Up { get { return Instance.up.Texture2D; } } + public static Texture2D ChoiceNodeOff { get { return Instance.choice_node_off.Texture2D; } } + public static Texture2D ChoiceNodeOn { get { return Instance.choice_node_on.Texture2D; } } + public static Texture2D CommandBackground { get { return Instance.command_background.Texture2D; } } + public static Texture2D EventNodeOff { get { return Instance.event_node_off.Texture2D; } } + public static Texture2D EventNodeOn { get { return Instance.event_node_on.Texture2D; } } + public static Texture2D PlayBig { get { return Instance.play_big.Texture2D; } } + public static Texture2D PlaySmall { get { return Instance.play_small.Texture2D; } } + public static Texture2D ProcessNodeOff { get { return Instance.process_node_off.Texture2D; } } + public static Texture2D ProcessNodeOn { get { return Instance.process_node_on.Texture2D; } } } }