From 8191a1b758cc348da344f438b10beaa79af7d6f1 Mon Sep 17 00:00:00 2001 From: esnya Date: Fri, 17 Sep 2021 23:53:33 +0900 Subject: [PATCH] :sparkles: feat: PrefabUdonVariables --- .../Udon/EsnyaUnityTools.Editor.Udon.asmdef | 3 +- .../Editor/Udon/PrefabUdonVariables.cs | 121 ++++++++++++++++++ .../Editor/Udon/PrefabUdonVariables.cs.meta | 11 ++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs create mode 100644 Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs.meta diff --git a/Assets/EsnyaUnityTools/Editor/Udon/EsnyaUnityTools.Editor.Udon.asmdef b/Assets/EsnyaUnityTools/Editor/Udon/EsnyaUnityTools.Editor.Udon.asmdef index 7db0042..8d09b28 100644 --- a/Assets/EsnyaUnityTools/Editor/Udon/EsnyaUnityTools.Editor.Udon.asmdef +++ b/Assets/EsnyaUnityTools/Editor/Udon/EsnyaUnityTools.Editor.Udon.asmdef @@ -4,7 +4,8 @@ "VRC.Udon", "VRC.Udon.Editor", "UdonSharp.Runtime", - "UdonSharp.Editor" + "UdonSharp.Editor", + "VRC.Udon.Serialization.OdinSerializer" ], "includePlatforms": [ "Editor" diff --git a/Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs b/Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs new file mode 100644 index 0000000..4ba9e82 --- /dev/null +++ b/Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using VRC.Udon; +using VRC.Udon.Common.Interfaces; +using VRC.Udon.Serialization.OdinSerializer; + +namespace EsnyaFactory +{ + [CreateAssetMenu(menuName = "EsnyaTools/PrefabUdonVariables")] + public class PrefabUdonVariables : ScriptableObject + { + [Serializable] + public struct UdonVariable + { + public string symbolName; + public UnityEngine.Object objectReference; + public string value; + } + + + [Serializable] + public struct UdonVariables + { + public UdonBehaviour udonInstance; + public string gameObjectName; + public UdonVariable[] variables; + } + + [Serializable] + public struct PrefabVariables + { + public GameObject prefabInstance; + public string prefabPath; + public UdonVariables[] udonVariables; + } + + [HideInInspector] public PrefabVariables[] udonVariables; + + public UdonVariables ScanUdon(UdonBehaviour udon) + { + return new UdonVariables() + { + udonInstance = udon, + gameObjectName = udon.gameObject.name, + variables = udon.publicVariables.VariableSymbols.Select(symbolName => + { + udon.publicVariables.TryGetVariableValue(symbolName, out object value); + return new UdonVariable() + { + symbolName = symbolName, + objectReference = value as UnityEngine.Object, + value = value?.ToString() ?? "null", + }; + }).OrderBy(v => v.symbolName).ToArray(), + }; + } + + public PrefabVariables ScanPrefab(string path) + { + var prefab = AssetDatabase.LoadAssetAtPath(path); + return new PrefabVariables() + { + prefabPath = path, + prefabInstance = prefab, + udonVariables = prefab.GetComponentsInChildren() + .Select(ScanUdon) + .Where(uv => uv.variables.Length > 0) + .OrderBy(uv => uv.udonInstance.GetInstanceID()).ToArray(), + }; + } + public void Scan() + { + udonVariables = AssetDatabase.FindAssets("t:GameObject", new[] { Path.GetDirectoryName(AssetDatabase.GetAssetPath(this)) }) + .Select(AssetDatabase.GUIDToAssetPath) + .Select(ScanPrefab) + .Where(pv => pv.udonVariables.Length > 0) + .OrderBy(pv => pv.prefabInstance.GetInstanceID()) + .ToArray(); + EditorUtility.SetDirty(this); + } + + private void Reset() => Scan(); + private void OnValidate() => Scan(); + } + + public class PrefabUdonVariablesScanner : AssetPostprocessor + { + private void OnPostprocessPrefab(GameObject root) + { + var path = AssetDatabase.GetAssetPath(root); + UnityEngine.Object.FindObjectsOfType() + .Where(puv => path.StartsWith(Path.GetDirectoryName(AssetDatabase.GetAssetPath(puv)))) + .ToList() + .ForEach(puv => puv.Scan()); + } + + [InitializeOnLoadMethod] + private static void RegisterCallbacks() + { + EditorSceneManager.sceneSaving += (_, __) => UnityEngine.Object.FindObjectsOfType() + .ToList() + .ForEach(puv => puv.Scan()); + } + } + + [CustomEditor(typeof(PrefabUdonVariables))] + public class PrefabUdonVariablesEditor : Editor + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (GUILayout.Button("Update Now")) (target as PrefabUdonVariables)?.Scan(); + } + } +} diff --git a/Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs.meta b/Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs.meta new file mode 100644 index 0000000..8b6ea68 --- /dev/null +++ b/Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dba914234891ddd458239d9a948eaa9a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: