An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
7.5 KiB

// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus).
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
namespace Fungus.EditorUtils
{
[CustomEditor(typeof(FungusEditorResources))]
internal class FungusEditorResourcesInspector : Editor
{
public override void OnInspectorGUI()
{
if (serializedObject.FindProperty("updateOnReloadScripts").boolValue)
{
GUILayout.Label("Updating...");
}
else
{
if (GUILayout.Button("Sync with EditorResources folder"))
{
FungusEditorResources.GenerateResourcesScript();
}
DrawDefaultInspector();
}
}
}
internal partial class FungusEditorResources : ScriptableObject
{
[Serializable]
internal class EditorTexture
{
[SerializeField] private Texture2D free;
[SerializeField] private Texture2D pro;
public Texture2D Texture2D
{
get { return EditorGUIUtility.isProSkin && pro != null ? pro : free; }
}
public EditorTexture(Texture2D free, Texture2D pro)
{
this.free = free;
this.pro = pro;
}
}
private static FungusEditorResources instance;
private static readonly string editorResourcesFolderName = "\"EditorResources\"";
[SerializeField] [HideInInspector] private bool updateOnReloadScripts = false;
internal static FungusEditorResources Instance
{
get
{
if (instance == null)
{
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;
}
}
return instance;
}
}
private static string GetRootFolder()
{
var rootGuid = AssetDatabase.FindAssets(editorResourcesFolderName)[0];
return AssetDatabase.GUIDToAssetPath(rootGuid);
}
internal static void GenerateResourcesScript()
{
// Get all unique filenames
var textureNames = new HashSet<string>();
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))
{
writer.WriteLine("// This code is part of the Fungus library (http://fungusgames.com) maintained by Chris Gregan (http://twitter.com/gofungus).");
writer.WriteLine("// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)");
writer.WriteLine("");
writer.WriteLine("using UnityEngine;");
writer.WriteLine("");
writer.WriteLine("namespace Fungus.EditorUtils");
writer.WriteLine("{");
writer.WriteLine(" internal partial class FungusEditorResources : ScriptableObject");
writer.WriteLine(" {");
foreach (var name in textureNames)
{
writer.WriteLine(" [SerializeField] private EditorTexture " + name + ";");
}
writer.WriteLine("");
foreach (var name in textureNames)
{
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 Instance." + name + ".Texture2D; } }");
}
writer.WriteLine(" }");
writer.WriteLine("}");
}
Instance.updateOnReloadScripts = true;
AssetDatabase.ImportAsset(relativePath);
}
[DidReloadScripts]
private static void OnDidReloadScripts()
{
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))
{
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;
}
}
}
}
instance.updateOnReloadScripts = false;
serializedObject.ApplyModifiedPropertiesWithoutUndo();
}
}
}