|
using System.Linq; |
|
using TMPro; |
|
using TMPro.EditorUtilities; |
|
using UnityEditor; |
|
using UnityEditor.Events; |
|
using UnityEditor.SceneManagement; |
|
using UnityEngine; |
|
using UnityEngine.UI; |
|
using VRC.Udon; |
|
|
|
// Adds automation so the text on the button matches the button's name. |
|
[CustomEditor(typeof(Button))] |
|
public class ButtonEditorEnhancer : UnityEditor.UI.ButtonEditor |
|
{ |
|
[SerializeField] private UdonBehaviour buttonOnClickUdonTarget; |
|
private int selectedEvent; |
|
|
|
public override void OnInspectorGUI() |
|
{ |
|
base.OnInspectorGUI(); |
|
|
|
// Get the selected object. Update its text so it matches the name of the object. |
|
// This is a grotty script. |
|
|
|
var obj = Selection.activeGameObject; |
|
if (!obj) |
|
{ |
|
return; |
|
} |
|
|
|
var text = Selection.activeGameObject.GetComponentInChildren<TMP_Text>(); |
|
if (text) |
|
{ |
|
text.text = obj.name; |
|
} |
|
|
|
buttonOnClickUdonTarget = (UdonBehaviour)EditorGUILayout.ObjectField("Target Udon Behaviour:", buttonOnClickUdonTarget, typeof(UdonBehaviour), true); |
|
if (!buttonOnClickUdonTarget) |
|
{ |
|
return; |
|
} |
|
|
|
// If we've provided an UdonTarget, set the button via some fun tricks, so we don't have to manually look up the name of the string corresponding to the exported Custom Event. |
|
|
|
// Get the event names via an utter nonsense lookup. |
|
var program = buttonOnClickUdonTarget.programSource.SerializedProgramAsset.RetrieveProgram(); |
|
if (program == null) |
|
{ |
|
return; |
|
} |
|
|
|
var events = program.EntryPoints.GetExportedSymbols(); |
|
|
|
// Get the user to pick an event via a dropdown menu. This is an int; stash it. |
|
selectedEvent = EditorGUILayout.Popup("Selected Event", selectedEvent, events.ToArray()); |
|
|
|
var buttonTarget = (Button) target; |
|
|
|
// Clear all instances of the UdonBehaviour from the OnClick listener list. |
|
// This means if you're using this automation you can't use the same UdonBehaviour twice in the same OnClick. |
|
// Frankly, if you, are, skill issue. 🎃. Just write a single function that calls both internally. If you're |
|
// doing something exceptionally cursed, just manually input the events! |
|
for (var i = 0; i < buttonTarget.onClick.GetPersistentEventCount(); i++) |
|
{ |
|
if (buttonTarget.onClick.GetPersistentTarget(i) != buttonOnClickUdonTarget) |
|
{ |
|
continue; |
|
} |
|
|
|
UnityEventTools.RemovePersistentListener(buttonTarget.onClick, i); |
|
} |
|
|
|
// Stick a string persistent listener that directs to trigger SCE on the UB using the event the user picked. |
|
UnityEventTools.AddStringPersistentListener(buttonTarget.onClick, buttonOnClickUdonTarget.SendCustomEvent, events[selectedEvent]); |
|
|
|
// Write to the object. Note that once we close this inspector window, the behaviour we used for this automation |
|
// will be cleared if we re-open the window. Which is totally a feature and not a limitation. |
|
|
|
// Leaving this here in case we mess with the serialized object in an update to this script. |
|
// serializedObject.ApplyModifiedProperties(); |
|
|
|
Undo.RecordObject(buttonTarget, "modified on-click events"); |
|
PrefabUtility.RecordPrefabInstancePropertyModifications(buttonTarget); |
|
} |
|
} |
|
|
|
// Adds automation so the name of the text object matches the text of the object. |
|
[CustomEditor(typeof(TextMeshProUGUI))] |
|
public class TMProTextEnhancer : TMP_EditorPanelUI |
|
{ |
|
public override void OnInspectorGUI() |
|
{ |
|
base.OnInspectorGUI(); |
|
|
|
// Get the selected object. Update its name so it matches the text of the object. |
|
// This is a grotty script. |
|
|
|
var obj = Selection.activeGameObject; |
|
if (!obj) |
|
{ |
|
return; |
|
} |
|
|
|
var text = Selection.activeGameObject.GetComponent<TMP_Text>(); |
|
if (text) |
|
{ |
|
obj.name = text.text; |
|
} |
|
} |
|
} |
|
|
The above code is hereby declared as part of the public domain; the original author declares no ownership over it. No relationship is assumed between original author and user.