Skip to content

Commit

Permalink
✨ feat: PrefabUdonVariables
Browse files Browse the repository at this point in the history
  • Loading branch information
esnya committed Sep 17, 2021
1 parent 9990a69 commit 8191a1b
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"VRC.Udon",
"VRC.Udon.Editor",
"UdonSharp.Runtime",
"UdonSharp.Editor"
"UdonSharp.Editor",
"VRC.Udon.Serialization.OdinSerializer"
],
"includePlatforms": [
"Editor"
Expand Down
121 changes: 121 additions & 0 deletions Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs
Original file line number Diff line number Diff line change
@@ -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<GameObject>(path);
return new PrefabVariables()
{
prefabPath = path,
prefabInstance = prefab,
udonVariables = prefab.GetComponentsInChildren<UdonBehaviour>()
.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<PrefabUdonVariables>()
.Where(puv => path.StartsWith(Path.GetDirectoryName(AssetDatabase.GetAssetPath(puv))))
.ToList()
.ForEach(puv => puv.Scan());
}

[InitializeOnLoadMethod]
private static void RegisterCallbacks()
{
EditorSceneManager.sceneSaving += (_, __) => UnityEngine.Object.FindObjectsOfType<PrefabUdonVariables>()
.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();
}
}
}
11 changes: 11 additions & 0 deletions Assets/EsnyaUnityTools/Editor/Udon/PrefabUdonVariables.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8191a1b

Please sign in to comment.