summaryrefslogtreecommitdiff
path: root/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components
diff options
context:
space:
mode:
Diffstat (limited to 'VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components')
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs19
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs62
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs17
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs.meta11
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs358
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs48
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs225
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs23
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs25
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs37
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs.meta10
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs109
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs.meta10
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs46
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs.meta10
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs29
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs130
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs91
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs57
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs19
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs70
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs.meta11
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs106
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs58
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs105
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs117
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs1524
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs215
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs.meta12
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs20
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs.meta12
48 files changed, 3790 insertions, 0 deletions
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs
new file mode 100644
index 00000000..297fc8fb
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs
@@ -0,0 +1,19 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using VRC.Core;
+
+[CustomEditor(typeof(ApiCache))]
+public class ApiCacheEditor : Editor {
+ public override void OnInspectorGUI()
+ {
+ foreach (System.Type type in ApiCache.cache.Keys)
+ {
+ Dictionary<string, ApiCache.CacheEntry> typeCache = ApiCache.cache[type];
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel(type.Name);
+ EditorGUILayout.LabelField(typeCache.Count.ToString());
+ EditorGUILayout.EndHorizontal();
+ }
+ }
+}
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs.meta
new file mode 100644
index 00000000..7c1cdd09
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/ApiCacheEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 39cdf3092ab81be4b9e623cb5a8819d8
+timeCreated: 1509575680
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs
new file mode 100644
index 00000000..8363d450
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+using Object = UnityEngine.Object;
+
+public class EditorCoroutine
+{
+ public static EditorCoroutine Start( IEnumerator _routine )
+ {
+ EditorCoroutine coroutine = new EditorCoroutine(_routine);
+ coroutine.start();
+ return coroutine;
+ }
+
+
+ public static EditorCoroutine Start(System.Action _action)
+ {
+ EditorCoroutine coroutine = new EditorCoroutine(_action);
+ coroutine.start();
+ return coroutine;
+ }
+
+ readonly IEnumerator routine;
+ EditorCoroutine( IEnumerator _routine )
+ {
+ routine = _routine;
+ }
+
+ readonly System.Action action;
+ EditorCoroutine(System.Action _action)
+ {
+ action = _action;
+ }
+
+ void start()
+ {
+ EditorApplication.update += update;
+ }
+ public void stop()
+ {
+ EditorApplication.update -= update;
+ }
+
+ void update()
+ {
+ if (routine != null)
+ {
+ if (!routine.MoveNext())
+ stop();
+ }
+ else if (action != null)
+ {
+ action();
+ stop();
+ }
+ else
+ stop();
+
+ }
+}
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs.meta
new file mode 100644
index 00000000..dc452288
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorCoroutine.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 89005ebc9543e0a4284893c09ca19b1d
+timeCreated: 1473271738
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs
new file mode 100644
index 00000000..32923b58
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs
@@ -0,0 +1,17 @@
+using UnityEditor;
+using UnityEngine.SceneManagement;
+
+[InitializeOnLoad]
+public static class EditorHandling
+{
+ static EditorHandling()
+ {
+ UnityEditor.SceneManagement.EditorSceneManager.sceneOpened += SceneOpenedCallback;
+ }
+
+ static void SceneOpenedCallback( Scene scene, UnityEditor.SceneManagement.OpenSceneMode mode)
+ {
+ // refresh window when scene is opened to display content images correctly
+ if (null != VRCSdkControlPanel.window) VRCSdkControlPanel.window.Reset();
+ }
+}
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs.meta
new file mode 100644
index 00000000..7657e22a
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EditorHandling.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3d6c2e367eaa9564ebf6267ec163cfbd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs
new file mode 100644
index 00000000..fcca3092
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs
@@ -0,0 +1,358 @@
+#if UNITY_EDITOR
+
+using UnityEngine;
+using UnityEditor;
+using UnityEditor.SceneManagement;
+using System.Collections.Generic;
+using System.Linq;
+using VRC.SDKBase;
+
+namespace VRCSDK2
+{
+#if VRC_SDK_VRCSDK2
+ [CustomEditor(typeof(VRCSDK2.VRC_EventHandler))]
+ public class EventHandlerEditor : UnityEditor.Editor
+ {
+ bool showDeferredEvents = false;
+
+ static VRCSDK2.VRC_EventHandler.VrcEventType lastAddedEventType = VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage;
+
+ public override void OnInspectorGUI()
+ {
+ VRCSDK2.VRC_EventHandler myTarget = (VRCSDK2.VRC_EventHandler)target;
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("ID:");
+ EditorGUILayout.EndHorizontal();
+
+ if (myTarget.GetComponent<VRCSDK2.VRC_Trigger>() != null)
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Add Events via the VRC_Trigger on this object.");
+ EditorGUILayout.EndHorizontal();
+ }
+ else
+ {
+ EditorGUI.BeginChangeCheck();
+
+ RenderOldEditor(myTarget);
+
+ if (EditorGUI.EndChangeCheck())
+ EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
+ }
+
+ if (myTarget.deferredEvents.Count > 0)
+ {
+ showDeferredEvents = EditorGUILayout.Foldout(showDeferredEvents, "Deferred Events");
+ if (showDeferredEvents)
+ RenderEvents(myTarget.deferredEvents);
+ }
+ }
+
+ int[] sendMessageMethodIndicies;
+ private void RenderOldEditor(VRCSDK2.VRC_EventHandler myTarget)
+ {
+ EditorGUILayout.HelpBox("Please use a VRC_Trigger in the future.", MessageType.Error);
+
+ if (GUILayout.Button("Add Event Handler"))
+ myTarget.Events.Add(new VRCSDK2.VRC_EventHandler.VrcEvent());
+
+ bool first = true;
+ int deleteEventIndex = -1;
+ if (sendMessageMethodIndicies == null || sendMessageMethodIndicies.Length != myTarget.Events.Count)
+ sendMessageMethodIndicies = new int[myTarget.Events.Count + 1];
+
+ for (int i = 0; i < myTarget.Events.Count; ++i)
+ {
+ if (!first)
+ EditorGUILayout.Separator();
+ first = false;
+
+ EditorGUILayout.LabelField("Event " + (i + 1).ToString());
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Event Name");
+ myTarget.Events[i].Name = EditorGUILayout.TextField(myTarget.Events[i].Name);
+ EditorGUILayout.EndHorizontal();
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Event Type");
+ myTarget.Events[i].EventType = (VRCSDK2.VRC_EventHandler.VrcEventType)EditorGUILayout.EnumPopup(myTarget.Events[i].EventType);
+ EditorGUILayout.EndHorizontal();
+
+ switch (myTarget.Events[i].EventType)
+ {
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationBool:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Variable");
+ myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Operation");
+ myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationFloat:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Variable");
+ myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Value");
+ myTarget.Events[i].ParameterFloat = EditorGUILayout.FloatField(myTarget.Events[i].ParameterFloat);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationTrigger:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Trigger");
+ myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AudioTrigger:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("AudioSource");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.MeshVisibility:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Mesh");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Operation");
+ myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.PlayAnimation:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Target");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Animation");
+ myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.RunConsoleCommand:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Command");
+ myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Receiver");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Message");
+
+ // sorry for this shit show. Below allows us to show a list of public methods, but also allow custom messages
+ var methods = VRC_EditorTools.GetAccessibleMethodsOnGameObject(myTarget.Events[i].ParameterObject);
+ List<string> methodList = methods.Values.Aggregate(new List<string>(), (acc, lst) => { acc.AddRange(lst.Select(mi => mi.Name)); return acc; });
+ methodList.Add("Custom Message");
+
+ string[] _choices = methodList.ToArray();
+
+ int currentIndex = methodList.Count - 1;
+
+ if (methodList.Contains(myTarget.Events[i].ParameterString))
+ currentIndex = methodList.IndexOf(myTarget.Events[i].ParameterString);
+
+ sendMessageMethodIndicies[i] = EditorGUILayout.Popup(currentIndex, _choices);
+
+ if (sendMessageMethodIndicies[i] != methodList.Count - 1)
+ {
+ myTarget.Events[i].ParameterString = _choices[sendMessageMethodIndicies[i]];
+ }
+ else
+ {
+ if (methodList.Contains(myTarget.Events[i].ParameterString))
+ myTarget.Events[i].ParameterString = "";
+
+ myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
+ }
+
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetGameObjectActive:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("GameObject");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Operation");
+ myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetParticlePlaying:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Target");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Operation");
+ myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.TeleportPlayer:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Location");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Align Room To Destination");
+ myTarget.Events[i].ParameterBoolOp = (VRCSDK2.VRC_EventHandler.VrcBooleanOp)EditorGUILayout.EnumPopup(myTarget.Events[i].ParameterBoolOp);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelURI:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("URI");
+ myTarget.Events[i].ParameterString = EditorGUILayout.TextField(myTarget.Events[i].ParameterString);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Panel");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelVolume:
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Volume");
+ myTarget.Events[i].ParameterFloat = EditorGUILayout.FloatField(myTarget.Events[i].ParameterFloat);
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Panel");
+ myTarget.Events[i].ParameterObject = (GameObject)EditorGUILayout.ObjectField(myTarget.Events[i].ParameterObject, typeof(GameObject), true);
+ EditorGUILayout.EndHorizontal();
+ break;
+ default:
+ EditorGUILayout.BeginHorizontal();
+ GUIStyle redText = new GUIStyle();
+ redText.normal.textColor = Color.red;
+ EditorGUILayout.LabelField("Unsupported event type", redText);
+ EditorGUILayout.EndHorizontal();
+ break;
+ }
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField("Delete " + myTarget.Events[i].Name + "?");
+ if (GUILayout.Button("delete"))
+ deleteEventIndex = i;
+ EditorGUILayout.EndHorizontal();
+
+ if (myTarget.Events[i].ParameterObject == null)
+ myTarget.Events[i].ParameterObject = myTarget.gameObject;
+ }
+
+
+ if (deleteEventIndex != -1)
+ myTarget.Events.RemoveAt(deleteEventIndex);
+ }
+
+ private void RenderEvents(IEnumerable<VRCSDK2.VRC_EventHandler.EventInfo> entries)
+ {
+ foreach (VRCSDK2.VRC_EventHandler.EventInfo entry in entries)
+ {
+ EditorGUILayout.PrefixLabel("Target");
+ EditorGUILayout.ObjectField(entry.evt.ParameterObject, typeof(GameObject), true);
+
+ EditorGUILayout.LabelField(string.Format("Name: {0}", entry.evt.Name));
+ EditorGUILayout.LabelField(string.Format("Type: {0}", entry.evt.EventType));
+ EditorGUILayout.LabelField(string.Format("Bool: {0}", entry.evt.ParameterBool));
+ EditorGUILayout.LabelField(string.Format("Float: {0}", entry.evt.ParameterFloat));
+ EditorGUILayout.LabelField(string.Format("Int: {0}", entry.evt.ParameterInt));
+ EditorGUILayout.LabelField(string.Format("String: {0}", entry.evt.ParameterString));
+
+ EditorGUILayout.Space();
+ }
+ }
+
+ public static void RenderEditor(VRCSDK2.VRC_EventHandler myTarget)
+ {
+ bool first = true;
+ int deleteEventIndex = -1;
+
+ for (int i = 0; i < myTarget.Events.Count; ++i)
+ {
+ if (!first)
+ EditorGUILayout.Separator();
+ first = false;
+
+ if (RenderEventHeader(myTarget, myTarget.Events[i]))
+ deleteEventIndex = i;
+
+ RenderEventHeader(myTarget, myTarget.Events[i]);
+
+ if (myTarget.Events[i].ParameterObject == null)
+ myTarget.Events[i].ParameterObject = myTarget.gameObject;
+ }
+
+ if (deleteEventIndex != -1)
+ myTarget.Events.RemoveAt(deleteEventIndex);
+ }
+
+ public static VRCSDK2.VRC_EventHandler.VrcEvent RenderAddEvent(VRCSDK2.VRC_EventHandler myTarget)
+ {
+ VRCSDK2.VRC_EventHandler.VrcEvent newEvent = null;
+
+ EditorGUILayout.BeginHorizontal();
+ lastAddedEventType = VRC_EditorTools.FilteredEnumPopup("New Event Type", lastAddedEventType, (v) => v != VRCSDK2.VRC_EventHandler.VrcEventType.SpawnObject && v != VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage);
+ if (GUILayout.Button("Add"))
+ {
+ newEvent = new VRCSDK2.VRC_EventHandler.VrcEvent
+ {
+ EventType = lastAddedEventType,
+ ParameterObject = myTarget.gameObject
+ };
+ myTarget.Events.Add(newEvent);
+ EditorUtility.SetDirty(myTarget);
+ }
+ EditorGUILayout.EndHorizontal();
+
+ return newEvent;
+ }
+
+ public static bool RenderEventHeader(VRCSDK2.VRC_EventHandler myTarget, VRCSDK2.VRC_EventHandler.VrcEvent evt)
+ {
+ EditorGUILayout.BeginHorizontal();
+ evt.EventType = VRC_EditorTools.FilteredEnumPopup("New Event Type", evt.EventType, (v) => v != VRCSDK2.VRC_EventHandler.VrcEventType.SpawnObject && v != VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage);
+ bool delete = GUILayout.Button("Remove");
+ EditorGUILayout.EndHorizontal();
+
+ return delete;
+ }
+ }
+
+ [CustomEditor(typeof(VRC.SDKBase.VRC_EventHandler))]
+ public class SDKBaseEventHandlerEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.LabelField("Event Handlers are not supported in VRCSDK3.");
+ if (GUILayout.Button("replace me with the correct VRC_EventHandler"))
+ {
+ var go = ((VRC.SDKBase.VRC_EventHandler)target).gameObject;
+ DestroyImmediate(target);
+ go.AddComponent<VRCSDK2.VRC_EventHandler>();
+ }
+ }
+ }
+#else
+
+ [CustomEditor(typeof(VRC.SDKBase.VRC_EventHandler))]
+ public class SDKBaseEventHandlerEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.LabelField("Event Handlers are not supported in VRCSDK3.");
+ if( GUILayout.Button("delete me") )
+ DestroyImmediate(target);
+ }
+ }
+
+#endif
+
+
+}
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs.meta
new file mode 100644
index 00000000..d0632d47
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/EventHandlerEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 4810e652e8242384c834320970702290
+timeCreated: 1454469344
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs
new file mode 100644
index 00000000..ab085ca3
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs
@@ -0,0 +1,48 @@
+#if VRC_SDK_VRCSDK2 && UNITY_EDITOR
+
+#pragma warning disable 0618
+
+using UnityEditor;
+using System.Collections;
+
+namespace VRCSDK2
+{
+ [CustomEditor(typeof(VRCSDK2.VRC_KeyEvents))]
+ public class VRC_KeyEventsEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
+ }
+ }
+
+ [CustomEditor(typeof(VRCSDK2.VRC_UseEvents))]
+ public class VRC_UseEventsEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
+ }
+ }
+
+ [CustomEditor(typeof(VRCSDK2.VRC_TriggerColliderEventTrigger))]
+ public class VRC_TriggerColliderEventTriggerEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
+ }
+ }
+
+ [CustomEditor(typeof(VRCSDK2.VRC_TimedEvents))]
+ public class VRC_TimedEventsEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.HelpBox("Obsolete. Please use a VRC_Trigger instead.", MessageType.Error);
+ }
+ }
+}
+
+#pragma warning restore 0618
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs.meta
new file mode 100644
index 00000000..d3b115e7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/OldTriggerEditors.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 482185bf29f12074dada194ffef6a682
+timeCreated: 1475877803
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs
new file mode 100644
index 00000000..c248f212
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs
@@ -0,0 +1,225 @@
+#if VRC_SDK_VRCSDK2
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using System.Collections.Generic;
+using VRC.SDK3.Editor;
+using VRC.SDKBase.Editor;
+
+[CustomEditor(typeof(VRCSDK2.VRC_AvatarDescriptor))]
+public class AvatarDescriptorEditor : Editor
+{
+ VRCSDK2.VRC_AvatarDescriptor avatarDescriptor;
+ VRC.Core.PipelineManager pipelineManager;
+
+ SkinnedMeshRenderer selectedMesh;
+ List<string> blendShapeNames = null;
+
+ bool shouldRefreshVisemes = false;
+
+ public override void OnInspectorGUI()
+ {
+ if (avatarDescriptor == null)
+ avatarDescriptor = (VRCSDK2.VRC_AvatarDescriptor)target;
+
+ if (pipelineManager == null)
+ {
+ pipelineManager = avatarDescriptor.GetComponent<VRC.Core.PipelineManager>();
+ if (pipelineManager == null)
+ avatarDescriptor.gameObject.AddComponent<VRC.Core.PipelineManager>();
+ }
+
+ // DrawDefaultInspector();
+
+ if(VRCSdkControlPanel.window != null)
+ {
+ if( GUILayout.Button( "Select this avatar in the SDK control panel" ) )
+ VRCSdkControlPanelAvatarBuilder.SelectAvatar(avatarDescriptor);
+ }
+
+ avatarDescriptor.ViewPosition = EditorGUILayout.Vector3Field("View Position", avatarDescriptor.ViewPosition);
+ //avatarDescriptor.Name = EditorGUILayout.TextField("Avatar Name", avatarDescriptor.Name);
+ avatarDescriptor.Animations = (VRCSDK2.VRC_AvatarDescriptor.AnimationSet)EditorGUILayout.EnumPopup("Default Animation Set", avatarDescriptor.Animations);
+ avatarDescriptor.CustomStandingAnims = (AnimatorOverrideController)EditorGUILayout.ObjectField("Custom Standing Anims", avatarDescriptor.CustomStandingAnims, typeof(AnimatorOverrideController), true, null);
+ avatarDescriptor.CustomSittingAnims = (AnimatorOverrideController)EditorGUILayout.ObjectField("Custom Sitting Anims", avatarDescriptor.CustomSittingAnims, typeof(AnimatorOverrideController), true, null);
+ avatarDescriptor.ScaleIPD = EditorGUILayout.Toggle("Scale IPD", avatarDescriptor.ScaleIPD);
+
+ avatarDescriptor.lipSync = (VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle)EditorGUILayout.EnumPopup("Lip Sync", avatarDescriptor.lipSync);
+ switch (avatarDescriptor.lipSync)
+ {
+ case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.Default:
+ if (GUILayout.Button("Auto Detect!"))
+ AutoDetectLipSync();
+ break;
+
+ case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBlendShape:
+ avatarDescriptor.VisemeSkinnedMesh = (SkinnedMeshRenderer)EditorGUILayout.ObjectField("Face Mesh", avatarDescriptor.VisemeSkinnedMesh, typeof(SkinnedMeshRenderer), true);
+ if (avatarDescriptor.VisemeSkinnedMesh != null)
+ {
+ DetermineBlendShapeNames();
+
+ int current = -1;
+ for (int b = 0; b < blendShapeNames.Count; ++b)
+ if (avatarDescriptor.MouthOpenBlendShapeName == blendShapeNames[b])
+ current = b;
+
+ string title = "Jaw Flap Blend Shape";
+ int next = EditorGUILayout.Popup(title, current, blendShapeNames.ToArray());
+ if (next >= 0)
+ avatarDescriptor.MouthOpenBlendShapeName = blendShapeNames[next];
+ }
+ break;
+
+ case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBone:
+ avatarDescriptor.lipSyncJawBone = (Transform)EditorGUILayout.ObjectField("Jaw Bone", avatarDescriptor.lipSyncJawBone, typeof(Transform), true);
+ break;
+
+ case VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.VisemeBlendShape:
+ SkinnedMeshRenderer prev = avatarDescriptor.VisemeSkinnedMesh;
+ avatarDescriptor.VisemeSkinnedMesh = (SkinnedMeshRenderer)EditorGUILayout.ObjectField("Face Mesh", avatarDescriptor.VisemeSkinnedMesh, typeof(SkinnedMeshRenderer), true);
+ if (avatarDescriptor.VisemeSkinnedMesh != prev)
+ shouldRefreshVisemes = true;
+ if (avatarDescriptor.VisemeSkinnedMesh != null)
+ {
+ DetermineBlendShapeNames();
+
+ if (avatarDescriptor.VisemeBlendShapes == null || avatarDescriptor.VisemeBlendShapes.Length != (int)VRCSDK2.VRC_AvatarDescriptor.Viseme.Count)
+ avatarDescriptor.VisemeBlendShapes = new string[(int)VRCSDK2.VRC_AvatarDescriptor.Viseme.Count];
+ for (int i = 0; i < (int)VRCSDK2.VRC_AvatarDescriptor.Viseme.Count; ++i)
+ {
+ int current = -1;
+ for (int b = 0; b < blendShapeNames.Count; ++b)
+ if (avatarDescriptor.VisemeBlendShapes[i] == blendShapeNames[b])
+ current = b;
+
+ string title = "Viseme: " + ((VRCSDK2.VRC_AvatarDescriptor.Viseme)i).ToString();
+ int next = EditorGUILayout.Popup(title, current, blendShapeNames.ToArray());
+ if (next >= 0)
+ avatarDescriptor.VisemeBlendShapes[i] = blendShapeNames[next];
+ }
+
+ if (shouldRefreshVisemes)
+ AutoDetectVisemes();
+ }
+ break;
+ }
+ EditorGUILayout.LabelField("Unity Version", avatarDescriptor.unityVersion);
+ }
+
+ void DetermineBlendShapeNames()
+ {
+ if (avatarDescriptor.VisemeSkinnedMesh != null &&
+ avatarDescriptor.VisemeSkinnedMesh != selectedMesh)
+ {
+ blendShapeNames = new List<string>();
+ blendShapeNames.Add("-none-");
+ selectedMesh = avatarDescriptor.VisemeSkinnedMesh;
+ if ((selectedMesh != null) && (selectedMesh.sharedMesh != null))
+ {
+ for (int i = 0; i < selectedMesh.sharedMesh.blendShapeCount; ++i)
+ blendShapeNames.Add(selectedMesh.sharedMesh.GetBlendShapeName(i));
+ }
+ }
+ }
+
+ void AutoDetectVisemes()
+ {
+
+ // prioritize strict - but fallback to looser - naming and don't touch user-overrides
+
+ List<string> blendShapes = new List<string>(blendShapeNames);
+ blendShapes.Remove("-none-");
+
+ for (int v = 0; v < avatarDescriptor.VisemeBlendShapes.Length; v++)
+ {
+ if (string.IsNullOrEmpty(avatarDescriptor.VisemeBlendShapes[v]))
+ {
+ string viseme = ((VRCSDK2.VRC_AvatarDescriptor.Viseme)v).ToString().ToLowerInvariant();
+
+ foreach (string s in blendShapes)
+ {
+ if (s.ToLowerInvariant() == "vrc.v_" + viseme)
+ {
+ avatarDescriptor.VisemeBlendShapes[v] = s;
+ goto next;
+ }
+ }
+ foreach (string s in blendShapes)
+ {
+ if (s.ToLowerInvariant() == "v_" + viseme)
+ {
+ avatarDescriptor.VisemeBlendShapes[v] = s;
+ goto next;
+ }
+ }
+ foreach (string s in blendShapes)
+ {
+ if (s.ToLowerInvariant().EndsWith(viseme))
+ {
+ avatarDescriptor.VisemeBlendShapes[v] = s;
+ goto next;
+ }
+ }
+ foreach (string s in blendShapes)
+ {
+ if (s.ToLowerInvariant() == viseme)
+ {
+ avatarDescriptor.VisemeBlendShapes[v] = s;
+ goto next;
+ }
+ }
+ foreach (string s in blendShapes)
+ {
+ if (s.ToLowerInvariant().Contains(viseme))
+ {
+ avatarDescriptor.VisemeBlendShapes[v] = s;
+ goto next;
+ }
+ }
+ next: { }
+ }
+ }
+
+ shouldRefreshVisemes = false;
+
+ }
+
+ void AutoDetectLipSync()
+ {
+ var smrs = avatarDescriptor.GetComponentsInChildren<SkinnedMeshRenderer>();
+ foreach (var smr in smrs)
+ {
+ if (smr.sharedMesh.blendShapeCount > 0)
+ {
+ avatarDescriptor.lipSyncJawBone = null;
+
+ if (smr.sharedMesh.blendShapeCount > 1)
+ {
+ avatarDescriptor.lipSync = VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.VisemeBlendShape;
+ avatarDescriptor.VisemeSkinnedMesh = smr;
+ shouldRefreshVisemes = true;
+ }
+ else
+ {
+ avatarDescriptor.lipSync = VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBlendShape;
+ avatarDescriptor.VisemeSkinnedMesh = null;
+ }
+
+ return;
+ }
+ }
+
+ Animator a = avatarDescriptor.GetComponent<Animator>();
+ if (!a)
+ EditorUtility.DisplayDialog("Ooops", "This avatar has no Animator and can have no lipsync.", "OK");
+ else if (a.GetBoneTransform(HumanBodyBones.Jaw) != null)
+ {
+ avatarDescriptor.lipSync = VRCSDK2.VRC_AvatarDescriptor.LipSyncStyle.JawFlapBone;
+ avatarDescriptor.lipSyncJawBone = avatarDescriptor.GetComponent<Animator>().GetBoneTransform(HumanBodyBones.Jaw);
+ avatarDescriptor.VisemeSkinnedMesh = null;
+ return;
+ }
+
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs.meta
new file mode 100644
index 00000000..efb9de93
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCAvatarDescriptorEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5e83254bb97e84795ac882692ae124ba
+timeCreated: 1450462624
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs
new file mode 100644
index 00000000..ab194e3b
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs
@@ -0,0 +1,23 @@
+#if VRC_SDK_VRCSDK2
+using UnityEngine;
+using System.Collections;
+using UnityEditor;
+using System;
+
+[CustomEditor(typeof(VRCSDK2.VRC_ObjectSpawn))]
+public class VRCObjectSpawnEditor : Editor
+{
+ VRCSDK2.VRC_ObjectSpawn spawn;
+
+ void OnEnable()
+ {
+ if (spawn == null)
+ spawn = (VRCSDK2.VRC_ObjectSpawn)target;
+ }
+
+ public override void OnInspectorGUI()
+ {
+ DrawDefaultInspector();
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs.meta
new file mode 100644
index 00000000..9e238711
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSpawnEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 26a75599848adb449b7aceed5090e35c
+timeCreated: 1463516633
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs
new file mode 100644
index 00000000..4272f049
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs
@@ -0,0 +1,25 @@
+#if VRC_SDK_VRCSDK2
+
+using UnityEngine;
+using System.Collections;
+using UnityEditor;
+using System;
+
+[CustomEditor(typeof(VRCSDK2.VRC_ObjectSync))]
+public class VRCObjectSyncEditor : Editor
+{
+ VRCSDK2.VRC_ObjectSync sync;
+
+ void OnEnable()
+ {
+ if (sync == null)
+ sync = (VRCSDK2.VRC_ObjectSync)target;
+ }
+
+ public override void OnInspectorGUI()
+ {
+ sync.SynchronizePhysics = EditorGUILayout.Toggle("Synchronize Physics",sync.SynchronizePhysics);
+ sync.AllowCollisionTransfer = EditorGUILayout.Toggle("Allow Collision Transfer", sync.AllowCollisionTransfer);
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs.meta
new file mode 100644
index 00000000..c95d4e32
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCObjectSyncEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: ed4aad2698d3b62408e69b57c7748791
+timeCreated: 1463516212
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs
new file mode 100644
index 00000000..693cd368
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs
@@ -0,0 +1,37 @@
+#if VRC_SDK_VRCSDK2
+
+using UnityEngine;
+using UnityEditor;
+
+public class VRCPlayerModEditorWindow : EditorWindow {
+
+ public delegate void AddModCallback();
+ public static AddModCallback addModCallback;
+
+ private static VRCSDK2.VRC_PlayerMods myTarget;
+
+ private static VRCSDK2.VRCPlayerModFactory.PlayerModType type;
+
+ public static void Init (VRCSDK2.VRC_PlayerMods target, AddModCallback callback)
+ {
+ // Get existing open window or if none, make a new one:
+ EditorWindow.GetWindow (typeof (VRCPlayerModEditorWindow));
+ addModCallback = callback;
+ myTarget = target;
+
+ type = VRCSDK2.VRCPlayerModFactory.PlayerModType.Jump;
+ }
+
+ void OnGUI ()
+ {
+ type = (VRCSDK2.VRCPlayerModFactory.PlayerModType)EditorGUILayout.EnumPopup("Mods", type);
+ if(GUILayout.Button("Add Mod"))
+ {
+ VRCSDK2.VRCPlayerMod mod = VRCSDK2.VRCPlayerModFactory.Create(type);
+ myTarget.AddMod(mod);
+ addModCallback();
+ }
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs.meta
new file mode 100644
index 00000000..e43182bd
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModEditorWindow.cs.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 8986a640e24a0754ea0aded12234b808
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs
new file mode 100644
index 00000000..5efaa351
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs
@@ -0,0 +1,109 @@
+#if VRC_SDK_VRCSDK2
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using System;
+
+namespace VRCSDK2
+{
+ [CustomEditor(typeof(VRCSDK2.VRC_PlayerMods))]
+ public class VRCPlayerModsEditor : UnityEditor.Editor
+ {
+ VRCSDK2.VRC_PlayerMods myTarget;
+
+ void OnEnable()
+ {
+ if(myTarget == null)
+ myTarget = (VRCSDK2.VRC_PlayerMods)target;
+ }
+
+ public override void OnInspectorGUI()
+ {
+ myTarget.isRoomPlayerMods = EditorGUILayout.Toggle("isRoomPlayerMods", myTarget.isRoomPlayerMods);
+
+ List<VRCSDK2.VRCPlayerMod> playerMods = myTarget.playerMods;
+ for(int i=0; i<playerMods.Count; ++i)
+ {
+ VRCSDK2.VRCPlayerMod mod = playerMods[i];
+ EditorGUILayout.BeginVertical("box");
+ EditorGUILayout.LabelField(mod.name, EditorStyles.boldLabel);
+ if( mod.allowNameEdit )
+ mod.name = EditorGUILayout.TextField( "Mod Name: ", mod.name );
+ for(int j=0; j<mod.properties.Count; ++j)
+ {
+ VRCSDK2.VRCPlayerModProperty prop = mod.properties[j];
+ myTarget.playerMods[i].properties[j] = DrawFieldForProp(prop);
+ }
+ if(GUILayout.Button ("Remove Mod"))
+ {
+ myTarget.RemoveMod(mod);
+ break;
+ }
+ EditorGUILayout.EndVertical();
+ }
+ if(GUILayout.Button("Add Mods"))
+ {
+ VRCPlayerModEditorWindow.AddModCallback adcb = OnInspectorGUI;
+ VRCPlayerModEditorWindow.Init(myTarget, adcb);
+ }
+ }
+
+ VRCSDK2.VRCPlayerModProperty DrawFieldForProp(VRCSDK2.VRCPlayerModProperty property)
+ {
+ if(property.type.SystemType == typeof(int))
+ {
+ property.intValue = EditorGUILayout.IntField(property.name, property.intValue);
+ }
+ else if(property.type.SystemType == typeof(float))
+ {
+ property.floatValue = EditorGUILayout.FloatField(property.name, property.floatValue);
+ }
+ else if(property.type.SystemType == typeof(string))
+ {
+ property.stringValue = EditorGUILayout.TextField(property.name, property.stringValue);
+ }
+ else if(property.type.SystemType == typeof(bool))
+ {
+ property.boolValue = EditorGUILayout.Toggle(property.name, property.boolValue);
+ }
+ else if(property.type.SystemType == typeof(GameObject))
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField( property.name );
+ property.gameObjectValue = (GameObject) EditorGUILayout.ObjectField( property.gameObjectValue, typeof( GameObject ), true );
+ EditorGUILayout.EndHorizontal();
+ }
+ else if(property.type.SystemType == typeof(KeyCode))
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField( property.name );
+ property.keyCodeValue = (KeyCode) EditorGUILayout.EnumPopup( property.keyCodeValue );
+ EditorGUILayout.EndHorizontal();
+ }
+ else if(property.type.SystemType == typeof(VRCSDK2.VRC_EventHandler.VrcBroadcastType))
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField( property.name );
+ property.broadcastValue = (VRCSDK2.VRC_EventHandler.VrcBroadcastType) EditorGUILayout.EnumPopup( property.broadcastValue );
+ EditorGUILayout.EndHorizontal();
+ }
+ else if(property.type.SystemType == typeof(VRCSDK2.VRCPlayerModFactory.HealthOnDeathAction))
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField( property.name );
+ property.onDeathActionValue = (VRCSDK2.VRCPlayerModFactory.HealthOnDeathAction) EditorGUILayout.EnumPopup( property.onDeathActionValue);
+ EditorGUILayout.EndHorizontal();
+ }
+ else if(property.type.SystemType == typeof(RuntimeAnimatorController))
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField( property.name );
+ property.animationController = (RuntimeAnimatorController) EditorGUILayout.ObjectField( property.animationController, typeof( RuntimeAnimatorController ), false );
+ EditorGUILayout.EndHorizontal();
+ }
+ return property;
+ }
+ }
+}
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs.meta
new file mode 100644
index 00000000..d0bad2ea
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerModsEditor.cs.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 792e7964a56e51f4188e1221751642e9
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs
new file mode 100644
index 00000000..167c2796
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs
@@ -0,0 +1,46 @@
+#if VRC_SDK_VRCSDK2
+
+using UnityEngine;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using System;
+
+[CustomEditor(typeof(VRCSDK2.VRC_Station))]
+public class VRCPlayerStationEditor : Editor
+{
+ VRCSDK2.VRC_Station myTarget;
+
+ SerializedProperty onRemoteEnter;
+ SerializedProperty onRemoteExit;
+ SerializedProperty onLocalEnter;
+ SerializedProperty onLocalExit;
+
+ void OnEnable()
+ {
+ if(myTarget == null)
+ myTarget = (VRCSDK2.VRC_Station)target;
+ onRemoteEnter = serializedObject.FindProperty("OnRemotePlayerEnterStation");
+ onRemoteExit = serializedObject.FindProperty("OnRemotePlayerExitStation");
+ onLocalEnter = serializedObject.FindProperty("OnLocalPlayerEnterStation");
+ onLocalExit = serializedObject.FindProperty("OnLocalPlayerExitStation");
+ }
+
+ public override void OnInspectorGUI()
+ {
+ myTarget.PlayerMobility = (VRC.SDKBase.VRCStation.Mobility)EditorGUILayout.EnumPopup("Player Mobility", myTarget.PlayerMobility);
+ myTarget.canUseStationFromStation = EditorGUILayout.Toggle("Can Use Station From Station", myTarget.canUseStationFromStation);
+ myTarget.animatorController = (RuntimeAnimatorController)EditorGUILayout.ObjectField("Animator Controller", myTarget.animatorController, typeof(RuntimeAnimatorController), false);
+ myTarget.disableStationExit = EditorGUILayout.Toggle("Disable Station Exit", myTarget.disableStationExit);
+ myTarget.seated = EditorGUILayout.Toggle("Seated", myTarget.seated);
+ myTarget.stationEnterPlayerLocation = (Transform)EditorGUILayout.ObjectField("Player Enter Location", myTarget.stationEnterPlayerLocation, typeof(Transform), true);
+ myTarget.stationExitPlayerLocation = (Transform)EditorGUILayout.ObjectField("Player Exit Location", myTarget.stationExitPlayerLocation, typeof(Transform), true);
+ myTarget.controlsObject = (VRC.SDKBase.VRC_ObjectApi)EditorGUILayout.ObjectField("API Object", myTarget.controlsObject, typeof(VRC.SDKBase.VRC_ObjectApi), false);
+
+ EditorGUILayout.PropertyField(onRemoteEnter, new GUIContent("On Remote Player Enter"));
+ EditorGUILayout.PropertyField(onRemoteExit, new GUIContent("On Remote Player Exit"));
+ EditorGUILayout.PropertyField(onLocalEnter, new GUIContent("On Local Player Enter"));
+ EditorGUILayout.PropertyField(onLocalExit, new GUIContent("On Local Player Exit"));
+ }
+}
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs.meta
new file mode 100644
index 00000000..f24108b2
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCPlayerStationEditor.cs.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 5262a02c32e41e047bdfdfc3b63db8ff
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs
new file mode 100644
index 00000000..616d8a8b
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs
@@ -0,0 +1,29 @@
+#if VRC_SDK_VRCSDK2
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+
+[CustomEditor (typeof(VRCSDK2.VRC_SceneDescriptor))]
+public class VRCSceneDescriptorEditor : Editor
+{
+ VRCSDK2.VRC_SceneDescriptor sceneDescriptor;
+ VRC.Core.PipelineManager pipelineManager;
+
+ public override void OnInspectorGUI()
+ {
+ if(sceneDescriptor == null)
+ sceneDescriptor = (VRCSDK2.VRC_SceneDescriptor)target;
+
+ if(pipelineManager == null)
+ {
+ pipelineManager = sceneDescriptor.GetComponent<VRC.Core.PipelineManager>();
+ if(pipelineManager == null)
+ sceneDescriptor.gameObject.AddComponent<VRC.Core.PipelineManager>();
+ }
+
+ DrawDefaultInspector();
+
+
+ }
+}
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs.meta
new file mode 100644
index 00000000..66325676
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRCSceneDescriptorEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: e9cbc493bbbc443fb92898aa84d221ec
+timeCreated: 1450463561
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs
new file mode 100644
index 00000000..c9026421
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs
@@ -0,0 +1,130 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+
+namespace VRCSDK2
+{
+ //[CustomPropertyDrawer(typeof(VRC_AvatarVariations.VariationCategory))]
+ //public class PropertyDrawer_AvatarVariation_VariationCategory : PropertyDrawer
+ //{
+ // public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
+ // {
+ // //EditorGUILayout.Label("blah");
+
+ // if (property == null)
+ // return;
+
+ // SerializedProperty nameProperty = property.FindPropertyRelative("name");
+ // //SerializedProperty mirrorProperty = property.FindPropertyRelative("mirror");
+ // //SerializedProperty typeProperty = property.FindPropertyRelative("type");
+ // //SerializedProperty valueProperty = null;
+ // //switch (typeProperty.enumValueIndex)
+ // //{
+ // // case (int)VRC_DataStorage.VrcDataType.Bool:
+ // // valueProperty = property.FindPropertyRelative("valueBool");
+ // // break;
+ // // case (int)VRC_DataStorage.VrcDataType.Float:
+ // // valueProperty = property.FindPropertyRelative("valueFloat");
+ // // break;
+ // // case (int)VRC_DataStorage.VrcDataType.Int:
+ // // valueProperty = property.FindPropertyRelative("valueInt");
+ // // break;
+ // // case (int)VRC_DataStorage.VrcDataType.String:
+ // // valueProperty = property.FindPropertyRelative("valueString");
+ // // break;
+ // // case (int)VRC_DataStorage.VrcDataType.SerializeObject:
+ // // valueProperty = property.FindPropertyRelative("serializeComponent");
+ // // break;
+ // // case (int)VRC_DataStorage.VrcDataType.None:
+ // // case (int)VRC_DataStorage.VrcDataType.SerializeBytes:
+ // // break;
+ // //}
+
+ // EditorGUI.BeginProperty(rect, label, property);
+
+ // int baseWidth = (int)(rect.width / 4);
+ // Rect nameRect = new Rect(rect.x, rect.y, baseWidth, rect.height);
+ // //Rect mirrorRect = new Rect(rect.x + baseWidth, rect.y, baseWidth, rect.height);
+ // //Rect typeRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth, rect.height);
+ // //Rect valueRect = new Rect(rect.x + baseWidth * 3, rect.y, baseWidth, rect.height);
+ // //Rect typeValueRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth * 2, rect.height);
+
+ // EditorGUI.PropertyField(nameRect, nameProperty, GUIContent.none);
+ // //EditorGUI.PropertyField(mirrorRect, mirrorProperty, GUIContent.none);
+
+ // //switch (mirrorProperty.enumValueIndex)
+ // //{
+ // // case (int)VRC_DataStorage.VrcDataMirror.None:
+ // // if (valueProperty == null)
+ // // VRC_EditorTools.FilteredEnumPopup<VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
+ // // else
+ // // {
+ // // VRC_EditorTools.FilteredEnumPopup<VRC_DataStorage.VrcDataType>(typeRect, typeProperty, t => true);
+ // // EditorGUI.PropertyField(valueRect, valueProperty, GUIContent.none);
+ // // }
+ // // break;
+ // // case (int)VRC_DataStorage.VrcDataMirror.SerializeComponent:
+ // // typeProperty.enumValueIndex = (int)VRC_DataStorage.VrcDataType.SerializeObject;
+ // // EditorGUI.PropertyField(typeValueRect, valueProperty, GUIContent.none);
+ // // break;
+ // // default:
+ // // VRC_EditorTools.FilteredEnumPopup<VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
+ // // break;
+ // //}
+
+ // EditorGUI.EndProperty();
+ // }
+ //}
+
+ //[CustomEditor(typeof(VRC_AvatarVariations))]
+ //public class VRC_AvatarVariationsEditor : Editor
+ //{
+ // SerializedProperty categories;
+
+ // void OnEnable()
+ // {
+ // categories = serializedObject.FindProperty("categories");
+ // }
+
+ // public override void OnInspectorGUI()
+ // {
+ // //serializedObject.Update();
+ // // EditorGUILayout.PropertyField(categories);
+ // //serializedObject.ApplyModifiedProperties();
+
+
+
+ // //if (target == null)
+ // // return;
+
+ // ////var prop = serializedObject.FindProperty("root");
+ // ////EditorGUILayout.PropertyField(prop, new GUIContent("Show Help"));
+ // //VRCSDK2.VRC_AvatarVariations variations = target as VRCSDK2.VRC_AvatarVariations;
+ // //if (variations.categories == null)
+ // // variations.categories = new VRC_AvatarVariations.VariationCategory[0];
+
+ // //foreach ( var vc in variations.categories )
+ // //{
+ // // vc.name = EditorGUILayout.TextField("Variation Name", vc.name);
+ // //// SerializedProperty triggers = triggersProperty.Copy();
+ // //// int triggersLength = triggers.arraySize;
+
+ // //// List<int> to_remove = new List<int>();
+ // //// for (int idx = 0; idx < triggersLength; ++idx)
+ // //// {
+ // //// SerializedProperty triggerProperty = triggers.GetArrayElementAtIndex(idx);
+ // //// }
+
+ // //// EditorGUILayout.LabelField("");
+ // ////// helpProperty = serializedObject.FindProperty("ShowHelp");
+ // ////// EditorGUILayout.PropertyField(helpProperty, new GUIContent("Show Help"));
+ // //}
+
+ // ////EditorGUILayout.
+
+ // DrawDefaultInspector();
+ // }
+ //}
+
+}
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs.meta
new file mode 100644
index 00000000..b4f3a9ff
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_AvatarVariationsEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: eeda995d0ceac6443a54716996eab52e
+timeCreated: 1511373338
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs
new file mode 100644
index 00000000..bdc19188
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs
@@ -0,0 +1,91 @@
+#if VRC_SDK_VRCSDK2 && UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+using VRC.SDKBase;
+
+namespace VRCSDK2
+{
+ [CustomPropertyDrawer(typeof(VRCSDK2.VRC_DataStorage.VrcDataElement))]
+ public class CustomDataElementDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
+ {
+ if (property == null)
+ return;
+
+ SerializedProperty nameProperty = property.FindPropertyRelative("name");
+ SerializedProperty mirrorProperty = property.FindPropertyRelative("mirror");
+ SerializedProperty typeProperty = property.FindPropertyRelative("type");
+ SerializedProperty valueProperty = null;
+ switch (typeProperty.enumValueIndex)
+ {
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataType.Bool:
+ valueProperty = property.FindPropertyRelative("valueBool");
+ break;
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataType.Float:
+ valueProperty = property.FindPropertyRelative("valueFloat");
+ break;
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataType.Int:
+ valueProperty = property.FindPropertyRelative("valueInt");
+ break;
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataType.String:
+ valueProperty = property.FindPropertyRelative("valueString");
+ break;
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataType.SerializeObject:
+ valueProperty = property.FindPropertyRelative("serializeComponent");
+ break;
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataType.None:
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataType.SerializeBytes:
+ break;
+ }
+
+ EditorGUI.BeginProperty(rect, label, property);
+
+ int baseWidth = (int)(rect.width / 4);
+ Rect nameRect = new Rect(rect.x, rect.y, baseWidth, rect.height);
+ Rect mirrorRect = new Rect(rect.x + baseWidth, rect.y, baseWidth, rect.height);
+ Rect typeRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth, rect.height);
+ Rect valueRect = new Rect(rect.x + baseWidth * 3, rect.y, baseWidth, rect.height);
+ Rect typeValueRect = new Rect(rect.x + baseWidth * 2, rect.y, baseWidth * 2, rect.height);
+
+ EditorGUI.PropertyField(nameRect, nameProperty, GUIContent.none);
+ EditorGUI.PropertyField(mirrorRect, mirrorProperty, GUIContent.none);
+
+ switch (mirrorProperty.enumValueIndex)
+ {
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataMirror.None:
+ if (valueProperty == null)
+ VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
+ else
+ {
+ VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_DataStorage.VrcDataType>(typeRect, typeProperty, t => true);
+ EditorGUI.PropertyField(valueRect, valueProperty, GUIContent.none);
+ }
+ break;
+ case (int)VRCSDK2.VRC_DataStorage.VrcDataMirror.SerializeComponent:
+ typeProperty.enumValueIndex = (int)VRCSDK2.VRC_DataStorage.VrcDataType.SerializeObject;
+ EditorGUI.PropertyField(typeValueRect, valueProperty, GUIContent.none);
+ break;
+ default:
+ VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_DataStorage.VrcDataType>(typeValueRect, typeProperty, t => true);
+ break;
+ }
+
+ EditorGUI.EndProperty();
+ }
+ }
+
+ [CustomEditor(typeof(VRCSDK2.VRC_DataStorage)), CanEditMultipleObjects]
+ public class VRC_DataStorageEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ VRCSDK2.VRC_ObjectSync os = ((VRCSDK2.VRC_DataStorage)target).GetComponent<VRCSDK2.VRC_ObjectSync>();
+ if (os != null && os.SynchronizePhysics)
+ EditorGUILayout.HelpBox("Consider either removing the VRC_ObjectSync or disabling SynchronizePhysics.", MessageType.Warning);
+
+ DrawDefaultInspector();
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs.meta
new file mode 100644
index 00000000..a46a6e7b
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DataStorageEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0ac7998a36f085844847acbc046d4e27
+timeCreated: 1478191469
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs
new file mode 100644
index 00000000..5eaf7be0
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs
@@ -0,0 +1,57 @@
+using UnityEngine;
+using UnityEditor;
+using VRC_DestructibleStandard = VRC.SDKBase.VRC_DestructibleStandard;
+using VRC.SDKBase;
+
+[CustomEditor(typeof(VRC_DestructibleStandard))]
+[CanEditMultipleObjects]
+public class VRC_DestructibleStandardEditor : Editor
+{
+ VRC_DestructibleStandard ds;
+
+ SerializedProperty maxHealth;
+ SerializedProperty currentHealth;
+ SerializedProperty healable;
+ SerializedProperty onDamagedTrigger;
+ SerializedProperty onDestroyedTrigger;
+ SerializedProperty onHealedTrigger;
+ SerializedProperty onFullHealedTrigger;
+
+ void OnEnable()
+ {
+ maxHealth = serializedObject.FindProperty("maxHealth");
+ currentHealth = serializedObject.FindProperty("currentHealth");
+ healable = serializedObject.FindProperty("healable");
+ onDamagedTrigger = serializedObject.FindProperty("onDamagedTrigger");
+ onDestroyedTrigger = serializedObject.FindProperty("onDestructedTrigger");
+ onHealedTrigger = serializedObject.FindProperty("onHealedTrigger");
+ onFullHealedTrigger = serializedObject.FindProperty("onFullHealedTrigger");
+ }
+
+ public override void OnInspectorGUI()
+ {
+ ds = (VRC_DestructibleStandard)target;
+
+ // Update the serializedProperty - always do this in the beginning of OnInspectorGUI.
+ serializedObject.Update ();
+
+ EditorGUILayout.PropertyField(maxHealth, new GUIContent("Max Health"));
+ EditorGUILayout.PropertyField(currentHealth, new GUIContent("Current Health"));
+ EditorGUILayout.PropertyField(healable, new GUIContent("Is Healable"));
+
+ EditorGUILayout.PropertyField(onDamagedTrigger, new GUIContent("On Damaged Trigger"));
+ VRC_EditorTools.DrawTriggerActionCallback("On Damaged Action", ds.onDamagedTrigger, ds.onDamagedEvent);
+
+ EditorGUILayout.PropertyField(onDestroyedTrigger, new GUIContent("On Destructed Trigger"));
+ VRC_EditorTools.DrawTriggerActionCallback("On Destructed Action", ds.onDestructedTrigger, ds.onDestructedEvent);
+
+ EditorGUILayout.PropertyField(onHealedTrigger, new GUIContent("On Healed Trigger"));
+ VRC_EditorTools.DrawTriggerActionCallback("On Healed Action", ds.onHealedTrigger, ds.onHealedEvent);
+
+ EditorGUILayout.PropertyField(onFullHealedTrigger, new GUIContent("On Full Healed Trigger"));
+ VRC_EditorTools.DrawTriggerActionCallback("On Full Healed Action", ds.onFullHealedTrigger, ds.onFullHealedEvent);
+
+ // Apply changes to the serializedProperty - always do this in the end of OnInspectorGUI.
+ serializedObject.ApplyModifiedProperties ();
+ }
+}
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs.meta
new file mode 100644
index 00000000..34d65d25
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_DestructibleStandardEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 3b63b118c0591b548ba1797e6be4292e
+timeCreated: 1477161996
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs
new file mode 100644
index 00000000..13686eae
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs
@@ -0,0 +1,19 @@
+#if VRC_SDK_VRCSDK2
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+[CustomEditor(typeof(VRCSDK2.VRC_ObjectSync))]
+public class VRC_ObjectSyncEditor : Editor {
+ public override void OnInspectorGUI()
+ {
+ VRCSDK2.VRC_ObjectSync c = ((VRCSDK2.VRC_ObjectSync)target);
+ if ((c.gameObject.GetComponent<Animator>() != null || c.gameObject.GetComponent<Animation>() != null) && c.SynchronizePhysics)
+ EditorGUILayout.HelpBox("If the Animator or Animation moves the root position of this object then it will conflict with physics synchronization.", MessageType.Warning);
+ if (c.GetComponent<VRCSDK2.VRC_DataStorage>() != null && c.SynchronizePhysics)
+ EditorGUILayout.HelpBox("Consider either removing the VRC_DataStorage or disabling SynchronizePhysics.", MessageType.Warning);
+ DrawDefaultInspector();
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs.meta
new file mode 100644
index 00000000..7cf90f30
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_ObjectSyncEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: e19a7147a2386554a8e4d6e414f190a2
+timeCreated: 1504908295
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs
new file mode 100644
index 00000000..947dba7d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs
@@ -0,0 +1,70 @@
+#if VRC_SDK_VRCSDK2 && UNITY_EDITOR
+using UnityEditor;
+using UnityEngine;
+
+namespace VRCSDK2
+{
+ [CustomEditor(typeof(VRCSDK2.VRC_Pickup))]
+ public class VRC_PickupEditor : UnityEditor.Editor
+ {
+ private void InspectorField(string propertyName, string humanName)
+ {
+ SerializedProperty propertyField = serializedObject.FindProperty(propertyName);
+ EditorGUILayout.PropertyField(propertyField, new GUIContent(humanName), true);
+ }
+
+ private SerializedProperty momentumTransferMethodProperty;
+ private SerializedProperty disallowTheftProperty;
+ private SerializedProperty exactGunProperty;
+ private SerializedProperty exactGripProperty;
+ private SerializedProperty allowManipulationWhenEquippedProperty;
+ private SerializedProperty orientationProperty;
+ private SerializedProperty autoHoldProperty;
+ private SerializedProperty interactionTextProperty;
+ private SerializedProperty useTextProperty;
+ private SerializedProperty throwVelocityBoostMinSpeedProperty;
+ private SerializedProperty throwVelocityBoostScaleProperty;
+ private SerializedProperty pickupableProperty;
+ private SerializedProperty proximityProperty;
+
+ public override void OnInspectorGUI()
+ {
+ momentumTransferMethodProperty = serializedObject.FindProperty("MomentumTransferMethod");
+ disallowTheftProperty = serializedObject.FindProperty("DisallowTheft");
+ exactGunProperty = serializedObject.FindProperty("ExactGun");
+ exactGripProperty = serializedObject.FindProperty("ExactGrip");
+ allowManipulationWhenEquippedProperty = serializedObject.FindProperty("allowManipulationWhenEquipped");
+ orientationProperty = serializedObject.FindProperty("orientation");
+ autoHoldProperty = serializedObject.FindProperty("AutoHold");
+ interactionTextProperty = serializedObject.FindProperty("InteractionText");
+ useTextProperty = serializedObject.FindProperty("UseText");
+ throwVelocityBoostMinSpeedProperty = serializedObject.FindProperty("ThrowVelocityBoostMinSpeed");
+ throwVelocityBoostScaleProperty = serializedObject.FindProperty("ThrowVelocityBoostScale");
+ pickupableProperty = serializedObject.FindProperty("pickupable");
+ proximityProperty = serializedObject.FindProperty("proximity");
+
+ EditorGUILayout.BeginVertical(GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 30));
+
+ EditorGUILayout.PropertyField(momentumTransferMethodProperty, new GUIContent("Momentum Transfer Method"));
+ EditorGUILayout.PropertyField(disallowTheftProperty, new GUIContent("Disallow Theft"));
+ EditorGUILayout.PropertyField(exactGunProperty, new GUIContent("Exact Gun"));
+ EditorGUILayout.PropertyField(exactGripProperty, new GUIContent("Exact Grip"));
+ EditorGUILayout.PropertyField(allowManipulationWhenEquippedProperty, new GUIContent("Allow Manipulation When Equipped"));
+ EditorGUILayout.PropertyField(orientationProperty, new GUIContent("Orientation"));
+ EditorGUILayout.PropertyField(autoHoldProperty, new GUIContent("AutoHold", "If the pickup is supposed to be aligned to the hand (i.e. orientation field is set to Gun or Grip), auto-detect means that it will be Equipped(not dropped when they release trigger), otherwise just hold as a normal pickup."));
+ EditorGUILayout.PropertyField(interactionTextProperty, new GUIContent("Interaction Text","Text displayed when user hovers over the pickup."));
+ if (autoHoldProperty.enumValueIndex != (int)VRCSDK2.VRC_Pickup.AutoHoldMode.No)
+ EditorGUILayout.PropertyField(useTextProperty, new GUIContent("Use Text", "Text to display describing action for clicking button, when this pickup is already being held."));
+ EditorGUILayout.PropertyField(throwVelocityBoostMinSpeedProperty, new GUIContent("Throw Velocity Boost Min Speed"));
+ EditorGUILayout.PropertyField(throwVelocityBoostScaleProperty, new GUIContent("Throw Velocity Boost Scale"));
+ EditorGUILayout.PropertyField(pickupableProperty, new GUIContent("Pickupable"));
+ EditorGUILayout.PropertyField(proximityProperty, new GUIContent("Proximity"));
+
+ EditorGUILayout.EndVertical();
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs.meta
new file mode 100644
index 00000000..02042125
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PickupEditor.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4aff4e5c0d600c845b29d7b8b7965d68
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs
new file mode 100644
index 00000000..e2138127
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs
@@ -0,0 +1,106 @@
+#if VRC_SDK_VRCSDK2
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEditor;
+using System;
+
+namespace VRCSDK2
+{
+ [CustomEditor(typeof(VRCSDK2.VRC_PlayerAudioOverride))]
+ public class VRC_PlayerAudioOverrideEditor : UnityEditor.Editor
+ {
+ private bool voShow = true;
+ private bool voAdv = false;
+ private bool avShow = true;
+ private bool avAdv = false;
+ private SerializedProperty prioProperty;
+ private SerializedProperty globalProperty;
+ private SerializedProperty regionProperty;
+ private SerializedProperty voGainProperty;
+ private SerializedProperty voNearProperty;
+ private SerializedProperty voFarProperty;
+ private SerializedProperty voRadiusProperty;
+ private SerializedProperty voDisableLpProperty;
+ private SerializedProperty avGainProperty;
+ private SerializedProperty avNearProperty;
+ private SerializedProperty avFarProperty;
+ private SerializedProperty avRadiusProperty;
+ private SerializedProperty avForceSpatialProperty;
+ private SerializedProperty avAllowCustomProperty;
+
+ public override void OnInspectorGUI()
+ {
+ globalProperty = serializedObject.FindProperty("global");
+ regionProperty = serializedObject.FindProperty("region");
+ prioProperty = serializedObject.FindProperty("regionPriority");
+
+ voGainProperty = serializedObject.FindProperty("VoiceGain");
+ voNearProperty = serializedObject.FindProperty("VoiceNear");
+ voFarProperty = serializedObject.FindProperty("VoiceFar");
+ voRadiusProperty = serializedObject.FindProperty("VoiceVolumetricRadius");
+ voDisableLpProperty = serializedObject.FindProperty("VoiceDisableLowpass");
+
+ avGainProperty = serializedObject.FindProperty("AvatarGainLimit");
+ avNearProperty = serializedObject.FindProperty("AvatarNearLimit");
+ avFarProperty = serializedObject.FindProperty("AvatarFarLimit");
+ avRadiusProperty = serializedObject.FindProperty("AvatarVolumetricRadiusLimit");
+ avForceSpatialProperty = serializedObject.FindProperty("AvatarForceSpatial");
+ avAllowCustomProperty = serializedObject.FindProperty("AvatarAllowCustomCurve");
+
+ serializedObject.Update();
+
+ EditorGUILayout.BeginVertical();
+
+ var ovr = serializedObject.targetObject as VRCSDK2.VRC_PlayerAudioOverride;
+
+ EditorGUILayout.PropertyField(globalProperty, new GUIContent("Global"));
+ if (!ovr.global)
+ {
+ EditorGUILayout.PropertyField(regionProperty, new GUIContent("Region"));
+ EditorGUILayout.PropertyField(prioProperty, new GUIContent("Priority"));
+ }
+
+ voShow = EditorGUILayout.Foldout(voShow, "Voice Settings");
+
+ if (voShow)
+ {
+ EditorGUILayout.PropertyField(voGainProperty, new GUIContent("Gain"));
+ EditorGUILayout.PropertyField(voFarProperty, new GUIContent("Far"));
+
+ EditorGUI.indentLevel++;
+ voAdv = EditorGUILayout.Foldout(voAdv, "Advanced Options");
+ if (voAdv)
+ {
+ EditorGUILayout.PropertyField(voNearProperty, new GUIContent("Near"));
+ EditorGUILayout.PropertyField(voRadiusProperty, new GUIContent("Volumetric Radius"));
+ EditorGUILayout.PropertyField(voDisableLpProperty, new GUIContent("Disable Lowpass Filter"));
+ }
+ EditorGUI.indentLevel--;
+ }
+
+ avShow = EditorGUILayout.Foldout(avShow, "Avatar Audio Limits");
+
+ if (avShow)
+ {
+ EditorGUILayout.PropertyField(avGainProperty, new GUIContent("Gain Limit"));
+ EditorGUILayout.PropertyField(avFarProperty, new GUIContent("Far Limit"));
+
+ EditorGUI.indentLevel++;
+ avAdv = EditorGUILayout.Foldout(avAdv, "Advanced Options");
+ if (avAdv)
+ {
+ EditorGUILayout.PropertyField(avNearProperty, new GUIContent("Near Limit"));
+ EditorGUILayout.PropertyField(avRadiusProperty, new GUIContent("Volumetric Radius Limit"));
+ EditorGUILayout.PropertyField(avForceSpatialProperty, new GUIContent("Force Spatial"));
+ EditorGUILayout.PropertyField(avAllowCustomProperty, new GUIContent("Allow Custom Curve"));
+ }
+ EditorGUI.indentLevel--;
+ }
+
+ EditorGUILayout.EndVertical();
+
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs.meta
new file mode 100644
index 00000000..d7bfd85c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_PlayerAudioOverrideEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5c545625e0bf93045ac1c5864141c5c1
+timeCreated: 1474315179
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs
new file mode 100644
index 00000000..c7145db2
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs
@@ -0,0 +1,58 @@
+#if VRC_SDK_VRCSDK2 && UNITY_EDITOR
+
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEditor;
+using System;
+
+namespace VRCSDK2
+{
+ [CustomEditor(typeof(VRCSDK2.VRC_SpatialAudioSource))]
+ public class VRC_SpatialAudioSourceEditor : UnityEditor.Editor
+ {
+ private bool showAdvancedOptions = false;
+ private SerializedProperty gainProperty;
+ private SerializedProperty nearProperty;
+ private SerializedProperty farProperty;
+ private SerializedProperty volRadiusProperty;
+ private SerializedProperty enableSpatialProperty;
+ private SerializedProperty useCurveProperty;
+
+ public override void OnInspectorGUI()
+ {
+ gainProperty = serializedObject.FindProperty("Gain");
+ nearProperty = serializedObject.FindProperty("Near");
+ farProperty = serializedObject.FindProperty("Far");
+ volRadiusProperty = serializedObject.FindProperty("VolumetricRadius");
+ enableSpatialProperty = serializedObject.FindProperty("EnableSpatialization");
+ useCurveProperty = serializedObject.FindProperty("UseAudioSourceVolumeCurve");
+
+ serializedObject.Update();
+
+ VRCSDK2.VRC_SpatialAudioSource target = serializedObject.targetObject as VRCSDK2.VRC_SpatialAudioSource;
+ AudioSource source = target.GetComponent<AudioSource>();
+
+ EditorGUILayout.BeginVertical();
+
+ EditorGUILayout.PropertyField(gainProperty, new GUIContent("Gain"));
+ EditorGUILayout.PropertyField(farProperty, new GUIContent("Far"));
+ showAdvancedOptions = EditorGUILayout.Foldout(showAdvancedOptions, "Advanced Options");
+ bool enableSp = enableSpatialProperty.boolValue;
+ if (showAdvancedOptions)
+ {
+ EditorGUILayout.PropertyField(nearProperty, new GUIContent("Near"));
+ EditorGUILayout.PropertyField(volRadiusProperty, new GUIContent("Volumetric Radius"));
+ EditorGUILayout.PropertyField(enableSpatialProperty, new GUIContent("Enable Spatialization"));
+ if (enableSp)
+ EditorGUILayout.PropertyField(useCurveProperty, new GUIContent("Use AudioSource Volume Curve"));
+ }
+
+ EditorGUILayout.EndVertical();
+
+ if (source != null)
+ source.spatialize = enableSp;
+ serializedObject.ApplyModifiedProperties();
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs.meta
new file mode 100644
index 00000000..3f7ca463
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SpatialAudioSourceEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0d2d4cba733f5eb4ba170368e67710d2
+timeCreated: 1474315179
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs
new file mode 100644
index 00000000..5498e5da
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs
@@ -0,0 +1,105 @@
+#if VRC_SDK_VRCSDK2
+
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using UnityEditorInternal;
+using VRC.SDKBase;
+
+[CustomPropertyDrawer(typeof(VRCSDK2.VRC_SyncVideoPlayer.VideoEntry))]
+public class CustomVideoEntryDrawer : PropertyDrawer
+{
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty source = property.FindPropertyRelative("Source");
+ SerializedProperty ratio = property.FindPropertyRelative("AspectRatio");
+ SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
+ SerializedProperty clip = property.FindPropertyRelative("VideoClip");
+ SerializedProperty url = property.FindPropertyRelative("URL");
+
+ return EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing
+ + EditorGUI.GetPropertyHeight(ratio, new GUIContent("Aspect Ratio"), true) + EditorGUIUtility.standardVerticalSpacing
+ + EditorGUI.GetPropertyHeight(speed, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing
+ + Mathf.Max(EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true), EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true)) + EditorGUIUtility.standardVerticalSpacing;
+ }
+
+ public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty source = property.FindPropertyRelative("Source");
+ SerializedProperty ratio = property.FindPropertyRelative("AspectRatio");
+ SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
+ SerializedProperty clip = property.FindPropertyRelative("VideoClip");
+ SerializedProperty url = property.FindPropertyRelative("URL");
+
+ EditorGUI.BeginProperty(rect, label, property);
+ float x = rect.x;
+ float y = rect.y;
+ float w = rect.width;
+ float h = EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing;
+ VRC_EditorTools.FilteredEnumPopup<UnityEngine.Video.VideoSource>(new Rect(x, y, w, h), source, (e) => e == UnityEngine.Video.VideoSource.Url);
+ y += h;
+
+ if (source.enumValueIndex == (int)UnityEngine.Video.VideoSource.Url)
+ {
+ h = EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), url);
+ y += h;
+ }
+ else
+ {
+ h = EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), clip);
+ y += h;
+ }
+
+ h = EditorGUI.GetPropertyHeight(ratio, new GUIContent("AspectRatio"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), ratio);
+ y += h;
+
+ h = EditorGUI.GetPropertyHeight(ratio, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), speed);
+ if (speed.floatValue == 0f)
+ speed.floatValue = 1f;
+ y += h;
+
+ EditorGUI.EndProperty();
+ }
+}
+
+[CustomEditor(typeof(VRCSDK2.VRC_SyncVideoPlayer))]
+public class SyncVideoPlayerEditor : Editor
+{
+ ReorderableList sourceList;
+
+ public override void OnInspectorGUI()
+ {
+ SerializedProperty searchRoot = serializedObject.FindProperty("VideoSearchRoot");
+ EditorGUILayout.PropertyField(searchRoot);
+ SerializedProperty maxQual = serializedObject.FindProperty("MaxStreamQuality");
+ EditorGUILayout.PropertyField(maxQual);
+
+ EditorGUILayout.Space();
+
+ sourceList.DoLayoutList();
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ private void OnEnable()
+ {
+ SerializedProperty videos = serializedObject.FindProperty("Videos");
+ sourceList = new ReorderableList(serializedObject, videos);
+ sourceList.drawElementCallback += (Rect rect, int index, bool active, bool focused) =>
+ {
+ EditorGUI.PropertyField(rect, serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index));
+ };
+ sourceList.elementHeightCallback += (int index) =>
+ {
+ SerializedProperty element = serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index);
+ return EditorGUI.GetPropertyHeight(element);
+ };
+ sourceList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, "Videos");
+ }
+}
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs.meta
new file mode 100644
index 00000000..616cee0f
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoPlayerEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: ae0e74693b7899f47bd98864f94b9311
+timeCreated: 1499468412
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs
new file mode 100644
index 00000000..198f7ffa
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs
@@ -0,0 +1,117 @@
+#if VRC_SDK_VRCSDK2
+
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using UnityEditorInternal;
+using VRC.SDKBase;
+
+[CustomPropertyDrawer(typeof(VRCSDK2.VRC_SyncVideoStream.VideoEntry))]
+public class CustomVideoStreamEntryDrawer : PropertyDrawer
+{
+ public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty source = property.FindPropertyRelative("Source");
+ SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
+ SerializedProperty clip = property.FindPropertyRelative("VideoClip");
+ SerializedProperty url = property.FindPropertyRelative("URL");
+ SerializedProperty live = property.FindPropertyRelative("SyncType");
+ SerializedProperty sync = property.FindPropertyRelative("SyncMinutes");
+
+ return EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing
+ + EditorGUI.GetPropertyHeight(speed, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing
+ + Mathf.Max(EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true), EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true)) + EditorGUIUtility.standardVerticalSpacing
+ + EditorGUI.GetPropertyHeight(live, new GUIContent("SyncType"), true) + EditorGUIUtility.standardVerticalSpacing
+ + EditorGUI.GetPropertyHeight(sync, new GUIContent("SyncMinutes"), true) + EditorGUIUtility.standardVerticalSpacing;
+ }
+
+ public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
+ {
+ SerializedProperty source = property.FindPropertyRelative("Source");
+ SerializedProperty speed = property.FindPropertyRelative("PlaybackSpeed");
+ SerializedProperty clip = property.FindPropertyRelative("VideoClip");
+ SerializedProperty url = property.FindPropertyRelative("URL");
+ SerializedProperty live = property.FindPropertyRelative("SyncType");
+ SerializedProperty sync = property.FindPropertyRelative("SyncMinutes");
+
+ EditorGUI.BeginProperty(rect, label, property);
+ float x = rect.x;
+ float y = rect.y;
+ float w = rect.width;
+ float h = EditorGUI.GetPropertyHeight(source, new GUIContent("Source"), true) + EditorGUIUtility.standardVerticalSpacing;
+ VRC_EditorTools.FilteredEnumPopup<UnityEngine.Video.VideoSource>(new Rect(x, y, w, h), source, (e) => e == UnityEngine.Video.VideoSource.Url);
+ y += h;
+
+ if (source.enumValueIndex == (int)UnityEngine.Video.VideoSource.Url)
+ {
+ h = EditorGUI.GetPropertyHeight(url, new GUIContent("URL"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), url);
+ y += h;
+ }
+ else
+ {
+ h = EditorGUI.GetPropertyHeight(clip, new GUIContent("VideoClip"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), clip);
+ y += h;
+ }
+
+ h = EditorGUI.GetPropertyHeight(speed, new GUIContent("Playback Speed"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), speed);
+ if (speed.floatValue == 0f)
+ speed.floatValue = 1f;
+ y += h;
+
+ h = EditorGUI.GetPropertyHeight(live, new GUIContent("SyncType"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), live);
+ y += h;
+
+ h = EditorGUI.GetPropertyHeight(sync, new GUIContent("SyncMinutes"), true) + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(new Rect(x, y, w, h), sync);
+ if (sync.floatValue < 1f)
+ sync.floatValue = 0;
+ y += h;
+
+ EditorGUI.EndProperty();
+ }
+}
+
+[CustomEditor(typeof(VRCSDK2.VRC_SyncVideoStream))]
+public class SyncVideoStreamEditor : Editor
+{
+ ReorderableList sourceList;
+
+ public override void OnInspectorGUI()
+ {
+ SerializedProperty searchRoot = serializedObject.FindProperty("VideoSearchRoot");
+ EditorGUILayout.PropertyField(searchRoot);
+ SerializedProperty maxQual = serializedObject.FindProperty("MaxStreamQuality");
+ EditorGUILayout.PropertyField(maxQual);
+ SerializedProperty autoStart = serializedObject.FindProperty("AutoStart");
+ EditorGUILayout.PropertyField(autoStart);
+
+ EditorGUILayout.Space();
+
+ sourceList.DoLayoutList();
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ private void OnEnable()
+ {
+ SerializedProperty videos = serializedObject.FindProperty("Videos");
+ sourceList = new ReorderableList(serializedObject, videos);
+ sourceList.drawElementCallback += (Rect rect, int index, bool active, bool focused) =>
+ {
+ EditorGUI.PropertyField(rect, serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index));
+ };
+ sourceList.elementHeightCallback += (int index) =>
+ {
+ SerializedProperty element = serializedObject.FindProperty("Videos").GetArrayElementAtIndex(index);
+ return EditorGUI.GetPropertyHeight(element);
+ };
+ sourceList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, "Videos");
+ }
+}
+
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs.meta
new file mode 100644
index 00000000..ad3b7ed2
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_SyncVideoStreamEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 3f9dccfed0b072f49a307b3f20a7e768
+timeCreated: 1528745185
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs
new file mode 100644
index 00000000..f137e724
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs
@@ -0,0 +1,1524 @@
+#if VRC_SDK_VRCSDK2 && UNITY_EDITOR
+
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEditor;
+using UnityEditorInternal;
+using System.Linq;
+using System.Collections.Generic;
+using System.Reflection;
+using System;
+using VRC.SDKBase;
+using VRC.SDKBase.Editor;
+
+namespace VRCSDK2
+{
+ [CustomPropertyDrawer(typeof(VRCSDK2.VRC_Trigger.CustomTriggerTarget))]
+ public class CustomTriggerTargetDrawer : PropertyDrawer
+ {
+ public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
+ {
+ if (Application.isPlaying)
+ {
+ EditorGUI.HelpBox(rect, "Trigger Editor disabled while application is running.", MessageType.Info);
+ return;
+ }
+
+ if (property == null)
+ return;
+
+ SerializedProperty objectProperty = property.FindPropertyRelative("TriggerObject");
+ SerializedProperty nameProperty = property.FindPropertyRelative("CustomName");
+
+ EditorGUI.BeginProperty(rect, label, property);
+
+ rect = EditorGUI.PrefixLabel(rect, GUIUtility.GetControlID(FocusType.Passive), label);
+ Rect objectRect = new Rect(rect.x, rect.y, rect.width / 2 - 5, rect.height);
+ Rect nameRect = new Rect(rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height);
+
+ VRCSDK2.VRC_Trigger current = null;
+ if (objectProperty.objectReferenceValue != null)
+ current = (objectProperty.objectReferenceValue as GameObject).GetComponent<VRCSDK2.VRC_Trigger>();
+ current = EditorGUI.ObjectField(objectRect, current, typeof(VRCSDK2.VRC_Trigger), true) as VRCSDK2.VRC_Trigger;
+ objectProperty.objectReferenceValue = current == null ? null : current.gameObject;
+
+ VRC_EditorTools.CustomTriggerPopup(nameRect, objectProperty, nameProperty);
+
+ EditorGUI.EndProperty();
+ }
+ }
+
+ [CustomEditor(typeof(VRCSDK2.VRC_Trigger)), CanEditMultipleObjects]
+ public class VRC_TriggerEditor : UnityEditor.Editor
+ {
+ private List<VRCSDK2.VRC_Trigger.TriggerType> ActiveTypes
+ {
+ get
+ {
+ List<VRCSDK2.VRC_Trigger.TriggerType> activeTypes = new List<VRCSDK2.VRC_Trigger.TriggerType>();
+
+ SerializedProperty triggers = triggersProperty.Copy();
+ int triggersLength = triggers.arraySize;
+
+ for (int idx = 0; idx < triggersLength; ++idx)
+ {
+ VRCSDK2.VRC_Trigger.TriggerType triggerType = (VRCSDK2.VRC_Trigger.TriggerType)triggers.GetArrayElementAtIndex(idx).FindPropertyRelative("TriggerType").intValue;
+ activeTypes.Add(triggerType);
+ }
+
+ return activeTypes;
+ }
+ }
+
+#pragma warning disable CS0618 // Type or member is obsolete
+ private static List<VRCSDK2.VRC_Trigger.TriggerType> hiddenTriggerTypes = new List<VRCSDK2.VRC_Trigger.TriggerType> { /*VRCSDK2.VRC_Trigger.TriggerType.OnDataStorageAdd, VRCSDK2.VRC_Trigger.TriggerType.OnDataStorageRemove*/ };
+ private static List<VRCSDK2.VRC_EventHandler.VrcEventType> hiddenEventTypes = new List<VRCSDK2.VRC_EventHandler.VrcEventType> { VRCSDK2.VRC_EventHandler.VrcEventType.MeshVisibility, VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage, VRCSDK2.VRC_EventHandler.VrcEventType.RunConsoleCommand };
+ private static List<VRCSDK2.VRC_EventHandler.VrcBroadcastType> unbufferedBroadcastTypes = new List<VRCSDK2.VRC_EventHandler.VrcBroadcastType> { VRCSDK2.VRC_EventHandler.VrcBroadcastType.AlwaysUnbuffered, VRCSDK2.VRC_EventHandler.VrcBroadcastType.MasterUnbuffered, VRCSDK2.VRC_EventHandler.VrcBroadcastType.OwnerUnbuffered, VRCSDK2.VRC_EventHandler.VrcBroadcastType.Local };
+ private static List<VRCSDK2.VRC_EventHandler.VrcBroadcastType> bufferOneBroadcastTypes = new List<VRCSDK2.VRC_EventHandler.VrcBroadcastType> { VRCSDK2.VRC_EventHandler.VrcBroadcastType.AlwaysBufferOne, VRCSDK2.VRC_EventHandler.VrcBroadcastType.MasterBufferOne, VRCSDK2.VRC_EventHandler.VrcBroadcastType.OwnerBufferOne };
+ private static List<VRCSDK2.VRC_EventHandler.VrcBroadcastType> hiddenBroadcastTypes = new List<VRCSDK2.VRC_EventHandler.VrcBroadcastType> { };
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ private ReorderableList[] eventLists = new ReorderableList[0];
+ private ReorderableList[] relayLists = new ReorderableList[0];
+ private ReorderableList[] objectLists = new ReorderableList[0];
+ private bool[] visible = new bool[0];
+
+ private SerializedProperty triggersProperty;
+ private SerializedProperty proximityProperty;
+ private SerializedProperty interactTextProperty;
+ private SerializedProperty ownershipProperty;
+ private SerializedProperty drawLinesProperty;
+
+ private Dictionary<string, object[]> rpcByteCache = new Dictionary<string, object[]>();
+
+ private VRCSDK2.VRC_Trigger.TriggerType addTriggerSelectedType = VRCSDK2.VRC_Trigger.TriggerType.Custom;
+
+ private void OnEnable()
+ {
+ rpcByteCache.Clear();
+ }
+
+ public override void OnInspectorGUI()
+ {
+#pragma warning disable CS0618 // Type or member is obsolete
+ bool showedOldWarning = false;
+ foreach (VRCSDK2.VRC_Trigger t in targets.Cast<VRCSDK2.VRC_Trigger>().Where(tr => tr != null))
+ {
+ if (!showedOldWarning && (t.GetComponent<VRCSDK2.VRC_UseEvents>() != null || t.GetComponent<VRCSDK2.VRC_KeyEvents>() != null || t.GetComponent<VRCSDK2.VRC_TriggerColliderEventTrigger>() != null || t.GetComponent<VRCSDK2.VRC_TimedEvents>() != null))
+ {
+ EditorGUILayout.HelpBox("Do not use VRC_Trigger in combination with deprecated event components.", MessageType.Error);
+ showedOldWarning = true;
+ }
+ VRCSDK2.VRC_EventHandler handler = t.GetComponent<VRCSDK2.VRC_EventHandler>();
+ if (handler != null)
+ handler.Events = new List<VRCSDK2.VRC_EventHandler.VrcEvent>();
+ }
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ triggersProperty = serializedObject.FindProperty("Triggers");
+ proximityProperty = serializedObject.FindProperty("proximity");
+ interactTextProperty = serializedObject.FindProperty("interactText");
+ ownershipProperty = serializedObject.FindProperty("TakesOwnershipIfNecessary");
+ drawLinesProperty = serializedObject.FindProperty("DrawLines");
+
+ serializedObject.Update();
+
+ SerializedProperty triggers = triggersProperty.Copy();
+ int triggersLength = triggers.arraySize;
+
+ if (eventLists.Length != triggersLength)
+ eventLists = new ReorderableList[triggersLength];
+
+ if (relayLists.Length != triggersLength)
+ relayLists = new ReorderableList[triggersLength];
+
+ if (objectLists.Length != triggersLength)
+ objectLists = new ReorderableList[triggersLength];
+
+ if (visible.Length != triggersLength)
+ {
+ bool[] newVisible = new bool[triggersLength];
+ for (int idx = 0; idx < visible.Length && idx < newVisible.Length; ++idx)
+ newVisible[idx] = visible[idx];
+ for (int idx = visible.Length; idx < newVisible.Length && idx < newVisible.Length; ++idx)
+ newVisible[idx] = true;
+ visible = newVisible;
+ }
+
+ EditorGUILayout.BeginVertical(GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 30));
+
+ EditorGUILayout.Space();
+
+ EditorGUILayout.PropertyField(ownershipProperty, new GUIContent("Take Ownership of Action Targets"));
+ VRCSDK2.VRC_Trigger.EditorGlobalTriggerLineMode = (VRCSDK2.VRC_Trigger.EditorTriggerLineMode)EditorPrefs.GetInt("VRCSDK2_triggerLineMode", 0);
+ if (VRCSDK2.VRC_Trigger.EditorGlobalTriggerLineMode == VRCSDK2.VRC_Trigger.EditorTriggerLineMode.PerTrigger)
+ EditorGUILayout.PropertyField(drawLinesProperty, new GUIContent("Draw Lines"));
+
+ EditorGUILayout.Space();
+
+ RenderTriggers();
+
+ EditorGUILayout.Space();
+
+ EditorGUILayout.BeginHorizontal();
+ GUILayout.Space(10);
+ EditorGUILayout.BeginVertical();
+
+ EditorGUILayout.EndVertical();
+ EditorGUILayout.EndHorizontal();
+
+ EditorGUILayout.EndVertical();
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ private void RenderHelpBox(string message, MessageType messageType)
+ {
+ if (VRCSettings.DisplayHelpBoxes || messageType == MessageType.Error || messageType == MessageType.Warning)
+ EditorGUILayout.HelpBox(message, messageType);
+ }
+
+ private void RenderTriggers()
+ {
+ GUIStyle triggerStyle = new GUIStyle(EditorStyles.helpBox);
+
+ SerializedProperty triggers = triggersProperty.Copy();
+ int triggersLength = triggers.arraySize;
+
+ List<int> to_remove = new List<int>();
+ for (int idx = 0; idx < triggersLength; ++idx)
+ {
+ SerializedProperty triggerProperty = triggers.GetArrayElementAtIndex(idx);
+ SerializedProperty broadcastProperty = triggerProperty.FindPropertyRelative("BroadcastType");
+
+ EditorGUILayout.BeginVertical(triggerStyle);
+
+ if (RenderTriggerHeader(triggerProperty, ref visible[idx]))
+ {
+ to_remove.Add(idx);
+ EditorGUILayout.EndVertical();
+
+ continue;
+ }
+
+ if (!visible[idx])
+ {
+ EditorGUILayout.EndVertical();
+ continue;
+ }
+
+ if (!unbufferedBroadcastTypes.Contains((VRCSDK2.VRC_EventHandler.VrcBroadcastType)broadcastProperty.intValue) &&
+ !bufferOneBroadcastTypes.Contains((VRCSDK2.VRC_EventHandler.VrcBroadcastType)broadcastProperty.intValue) &&
+ ActiveEvents(triggerProperty).Any(e => e == VRCSDK2.VRC_EventHandler.VrcEventType.SendRPC))
+ RenderHelpBox("Consider using unbuffered broadcasts with RPCs.", MessageType.Error);
+
+ EditorGUILayout.Separator();
+
+ RenderTriggerEditor(triggerProperty, idx);
+
+ if (eventLists.Length == triggersLength)
+ {
+ EditorGUILayout.Separator();
+
+ if (triggerProperty.FindPropertyRelative("TriggerType").intValue != (int)VRCSDK2.VRC_Trigger.TriggerType.Relay)
+ {
+ RenderTriggerEventsEditor(triggerProperty, idx);
+
+ EditorGUILayout.Separator();
+ }
+ }
+ EditorGUILayout.EndVertical();
+ }
+
+ foreach (int idx in ((IEnumerable<int>)to_remove).Reverse())
+ triggersProperty.Copy().DeleteArrayElementAtIndex(idx);
+
+ RenderAddTrigger();
+ }
+
+ private void RenderTriggerEditor(SerializedProperty triggerProperty, int idx)
+ {
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("AfterSeconds"), new GUIContent("Delay in Seconds"));
+
+ VRC_Trigger.TriggerType triggerType = (VRC_Trigger.TriggerType)triggerProperty.FindPropertyRelative("TriggerType").intValue;
+ switch (triggerType)
+ {
+ case VRCSDK2.VRC_Trigger.TriggerType.Custom:
+ RenderCustom(triggerProperty);
+ break;
+ case VRCSDK2.VRC_Trigger.TriggerType.Relay:
+ RenderRelay(triggerProperty, idx);
+ break;
+ case VRCSDK2.VRC_Trigger.TriggerType.OnEnterTrigger:
+ case VRCSDK2.VRC_Trigger.TriggerType.OnExitTrigger:
+ case VRCSDK2.VRC_Trigger.TriggerType.OnEnterCollider:
+ case VRCSDK2.VRC_Trigger.TriggerType.OnExitCollider:
+ RenderCollider(triggerProperty);
+ break;
+ case VRCSDK2.VRC_Trigger.TriggerType.OnKeyDown:
+ case VRCSDK2.VRC_Trigger.TriggerType.OnKeyUp:
+ RenderKey(triggerProperty);
+ break;
+ case VRCSDK2.VRC_Trigger.TriggerType.OnTimer:
+ RenderTimer(triggerProperty);
+ break;
+ case VRCSDK2.VRC_Trigger.TriggerType.OnDataStorageChange:
+ // case VRCSDK2.VRC_Trigger.TriggerType.OnDataStorageAdd:
+ // case VRCSDK2.VRC_Trigger.TriggerType.OnDataStorageRemove:
+ RenderDataStorage(triggerProperty);
+ break;
+ case VRCSDK2.VRC_Trigger.TriggerType.OnParticleCollision:
+ //RenderHelpBox("Triggers for each particle in attached particle system that collides with something.", MessageType.Info);
+ RenderCollider(triggerProperty);
+ break;
+ default:
+ if (VRCSDK2.VRC_Trigger.TypeCollections.InteractiveTypes.Contains(triggerType) || VRCSDK2.VRC_Trigger.TypeCollections.PickupTypes.Contains(triggerType))
+ RenderInteractableEditor();
+ else
+ RenderEmpty(triggerProperty);
+ break;
+ }
+ }
+
+ private List<VRCSDK2.VRC_EventHandler.VrcEventType> ActiveEvents(SerializedProperty triggerProperty)
+ {
+ List<VRCSDK2.VRC_EventHandler.VrcEventType> activeTypes = new List<VRCSDK2.VRC_EventHandler.VrcEventType>();
+
+ SerializedProperty events = triggerProperty.FindPropertyRelative("Events").Copy();
+ int eventsLength = events.arraySize;
+
+ for (int idx = 0; idx < eventsLength; ++idx)
+ {
+ VRCSDK2.VRC_EventHandler.VrcEventType eventType = (VRCSDK2.VRC_EventHandler.VrcEventType)events.GetArrayElementAtIndex(idx).FindPropertyRelative("EventType").intValue;
+ activeTypes.Add(eventType);
+ }
+
+ return activeTypes;
+ }
+
+ private void RenderAddTrigger()
+ {
+ Rect rect = EditorGUILayout.BeginHorizontal(GUILayout.Height(15f));
+ EditorGUILayout.Space();
+
+ Rect selectedRect = new Rect(rect.x, rect.y, rect.width / 4 * 3 - 5, rect.height);
+ Rect addRect = new Rect(selectedRect.x + selectedRect.width + 5, rect.y, rect.width / 4, rect.height);
+
+ bool showStationTypes = serializedObject.targetObjects.Any(o => (o as VRCSDK2.VRC_Trigger).GetComponent<VRCSDK2.VRC_Station>() != null);
+ System.Func<VRCSDK2.VRC_Trigger.TriggerType, bool> predicate =
+ v => hiddenTriggerTypes.Contains(v) == false && (showStationTypes || (v != VRCSDK2.VRC_Trigger.TriggerType.OnStationEntered && v != VRCSDK2.VRC_Trigger.TriggerType.OnStationExited));
+
+ addTriggerSelectedType = VRC_EditorTools.FilteredEnumPopup(selectedRect, addTriggerSelectedType, predicate);
+
+ if (GUI.Button(addRect, "Add"))
+ {
+ SerializedProperty triggersAry = triggersProperty;
+
+ // hacks
+ triggersAry.Next(true);
+ triggersAry.Next(true);
+
+ int triggersLength = triggersAry.intValue;
+ triggersAry.intValue = triggersLength + 1;
+ triggersAry.Next(true);
+
+ for (int idx = 0; idx < triggersLength; ++idx)
+ triggersAry.Next(false);
+
+ triggersAry.FindPropertyRelative("TriggerType").intValue = (int)addTriggerSelectedType;
+ triggersAry.FindPropertyRelative("BroadcastType").intValue = (int)VRCSDK2.VRC_EventHandler.VrcBroadcastType.AlwaysBufferOne;
+ triggersAry.FindPropertyRelative("TriggerIndividuals").boolValue = true;
+ triggersAry.FindPropertyRelative("Layers").intValue = LayerMask.GetMask("Default");
+ }
+
+ EditorGUILayout.EndHorizontal();
+ }
+
+ private bool RenderTriggerHeader(SerializedProperty triggerProperty, ref bool expand)
+ {
+ bool delete = false;
+
+ if (!delete)
+ {
+ VRCSDK2.VRC_EventHandler.VrcBroadcastType? broadcast = null;
+
+ Rect rect = EditorGUILayout.BeginHorizontal(GUILayout.Height(15f));
+ EditorGUILayout.Space();
+
+ int baseWidth = (int)((rect.width - 40) / 4);
+
+ Rect foldoutRect = new Rect(rect.x + 10, rect.y, 20, rect.height);
+ Rect typeRect = new Rect(rect.x + 20, rect.y, baseWidth, rect.height);
+ Rect broadcastRect = new Rect(rect.x + 25 + baseWidth, rect.y, baseWidth, rect.height);
+ Rect randomRect = new Rect(rect.x + 30 + baseWidth * 2, rect.y, baseWidth, rect.height);
+ Rect removeRect = new Rect(rect.x + 35 + baseWidth * 3, rect.y, baseWidth, rect.height);
+
+ expand = EditorGUI.Foldout(foldoutRect, expand, GUIContent.none);
+
+ SerializedProperty triggerTypeProperty = triggerProperty.FindPropertyRelative("TriggerType");
+ VRCSDK2.VRC_Trigger.TriggerType currentType = (VRCSDK2.VRC_Trigger.TriggerType)triggerTypeProperty.intValue;
+
+ SerializedProperty nameProperty = triggerProperty.FindPropertyRelative("Name");
+ if (string.IsNullOrEmpty(nameProperty.stringValue))
+ nameProperty.stringValue = "Unnamed";
+
+ bool showStationTypes = serializedObject.targetObjects.Any(o => (o as VRCSDK2.VRC_Trigger).GetComponent<VRCSDK2.VRC_Station>() != null);
+ System.Func<string, string> rename = s => s == "Custom" ? s + " (" + nameProperty.stringValue + ")" : s;
+ System.Func<VRCSDK2.VRC_Trigger.TriggerType, bool> predicate =
+ v => hiddenTriggerTypes.Contains(v) == false && (showStationTypes || (v != VRCSDK2.VRC_Trigger.TriggerType.OnStationEntered && v != VRCSDK2.VRC_Trigger.TriggerType.OnStationExited));
+
+ triggerTypeProperty.intValue = (int)VRC_EditorTools.FilteredEnumPopup(typeRect, currentType, predicate, rename);
+ currentType = (VRCSDK2.VRC_Trigger.TriggerType)triggerTypeProperty.intValue;
+
+ SerializedProperty broadcastTypeProperty = triggerProperty.FindPropertyRelative("BroadcastType");
+ List<VRCSDK2.VRC_EventHandler.VrcEventType> activeEvents = ActiveEvents(triggerProperty);
+ if ((VRCSDK2.VRC_Trigger.TriggerType)triggerTypeProperty.intValue == VRCSDK2.VRC_Trigger.TriggerType.Relay || activeEvents.Contains(VRCSDK2.VRC_EventHandler.VrcEventType.SpawnObject))
+ {
+ broadcast = VRCSDK2.VRC_EventHandler.VrcBroadcastType.Always;
+ broadcastTypeProperty.intValue = (int)broadcast;
+ }
+ else
+ {
+ VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_EventHandler.VrcBroadcastType>(broadcastRect, broadcastTypeProperty, b => !hiddenBroadcastTypes.Contains(b));
+ broadcast = (VRCSDK2.VRC_EventHandler.VrcBroadcastType)broadcastTypeProperty.intValue;
+ }
+
+ SerializedProperty probabilitiesProperty = triggerProperty.FindPropertyRelative("Probabilities");
+ SerializedProperty probabilityLockProperty = triggerProperty.FindPropertyRelative("ProbabilityLock");
+ SerializedProperty eventsProperty = triggerProperty.FindPropertyRelative("Events");
+
+ if (triggerProperty.FindPropertyRelative("Events").arraySize < 1)
+ GUI.enabled = false;
+ if (GUI.Toggle(randomRect, probabilitiesProperty.arraySize > 0, new GUIContent(" Randomize")))
+ probabilityLockProperty.arraySize = probabilitiesProperty.arraySize = eventsProperty.arraySize;
+ else
+ probabilityLockProperty.arraySize = probabilitiesProperty.arraySize = 0;
+ GUI.enabled = true;
+
+ if (GUI.Button(removeRect, "Remove"))
+ delete = true;
+
+ EditorGUILayout.EndHorizontal();
+
+ if (broadcast.HasValue && expand)
+ {
+ string message = null;
+ switch (broadcast.Value)
+ {
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.Always:
+ message = "All are able to activate the trigger for everyone, and late-joiners will also trigger it.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.AlwaysUnbuffered:
+ message = "All are able to activate the trigger for everyone, but late-joiners will not trigger it.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.Local:
+ message = "All are able to activate the trigger for themselves only.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.Master:
+ message = "Only the Master is able to activate the trigger for everyone, and late-joiners will also trigger it.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.MasterUnbuffered:
+ message = "Only the Master is able to activate the trigger for everyone, but late-joiners will not trigger it.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.Owner:
+ message = "Only the Owner is able to activate the trigger for everyone, and late-joiners will also trigger it.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.OwnerUnbuffered:
+ message = "Only the Owner is able to activate the trigger for everyone, but late-joiners will not trigger it.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.AlwaysBufferOne:
+ message = "All are able to activate the trigger for everyone, and late-joiners will trigger the most recent one.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.MasterBufferOne:
+ message = "Only the Master is able to activate the trigger for everyone, and late-joiners will trigger the most recent one.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcBroadcastType.OwnerBufferOne:
+ message = "Only the Owner is able to activate the trigger for everyone, and late-joiners will trigger the most recent one.";
+ break;
+ }
+ if (message != null)
+ RenderHelpBox(message, MessageType.Info);
+ }
+ }
+
+ return delete;
+ }
+
+ private void RenderInteractableEditor()
+ {
+ EditorGUILayout.PropertyField(interactTextProperty, new GUIContent("Interaction Text"));
+ proximityProperty.floatValue = EditorGUILayout.Slider("Proximity", proximityProperty.floatValue, 0f, 100f);
+ }
+
+ private void RenderTriggerEventsEditor(SerializedProperty triggerProperty, int idx)
+ {
+ if (eventLists[idx] == null)
+ {
+ ReorderableList newList = new ReorderableList(serializedObject, triggerProperty.FindPropertyRelative("Events"), true, true, true, true);
+ newList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, "Actions");
+ newList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
+ {
+ SerializedProperty eventsListProperty = triggerProperty.FindPropertyRelative("Events");
+ SerializedProperty probabilitiesProperty = triggerProperty.FindPropertyRelative("Probabilities");
+ SerializedProperty probabilityLockProperty = triggerProperty.FindPropertyRelative("ProbabilityLock");
+ SerializedProperty shadowListProperty = triggerProperty.FindPropertyRelative("DataStorageShadowValues");
+
+ if (shadowListProperty != null && shadowListProperty.arraySize != eventsListProperty.arraySize)
+ shadowListProperty.arraySize = eventsListProperty.arraySize;
+
+ SerializedProperty shadowProperty = shadowListProperty == null ? null : shadowListProperty.GetArrayElementAtIndex(index);
+ SerializedProperty eventProperty = eventsListProperty.GetArrayElementAtIndex(index);
+ SerializedProperty eventTypeProperty = eventProperty.FindPropertyRelative("EventType");
+ SerializedProperty parameterStringProperty = eventProperty.FindPropertyRelative("ParameterString");
+
+ string label = ((VRCSDK2.VRC_EventHandler.VrcEventType)eventTypeProperty.intValue).ToString();
+ if (!string.IsNullOrEmpty(parameterStringProperty.stringValue))
+ label += " (" + parameterStringProperty.stringValue + ")";
+
+ if (probabilitiesProperty.arraySize == 0)
+ EditorGUI.LabelField(rect, label);
+ else
+ {
+ Rect labelRect = new Rect(rect.x, rect.y, rect.width / 2, rect.height);
+ Rect sliderLockRect = new Rect(rect.x + rect.width / 2, rect.y, 30, rect.height);
+ Rect sliderRect = new Rect(rect.x + rect.width / 2 + 30, rect.y, rect.width / 2 - 30, rect.height);
+
+ EditorGUI.LabelField(labelRect, label);
+
+ probabilityLockProperty.GetArrayElementAtIndex(index).boolValue = GUI.Toggle(sliderLockRect, probabilityLockProperty.GetArrayElementAtIndex(index).boolValue, new GUIContent());
+ probabilitiesProperty.GetArrayElementAtIndex(index).floatValue = EditorGUI.Slider(sliderRect, new GUIContent(), probabilitiesProperty.GetArrayElementAtIndex(index).floatValue, 0f, 1f);
+
+ bool allLocked = true;
+ for (int pIdx = 0; pIdx < probabilitiesProperty.arraySize; ++pIdx)
+ allLocked = allLocked && probabilityLockProperty.GetArrayElementAtIndex(pIdx).boolValue;
+ if (allLocked)
+ for (int pIdx = 0; pIdx < probabilitiesProperty.arraySize; ++pIdx)
+ if (pIdx != index)
+ probabilitiesProperty.GetArrayElementAtIndex(pIdx).floatValue = probabilitiesProperty.GetArrayElementAtIndex(index).floatValue;
+
+ // Squish 'em down
+ float probabilitySum = 1f;
+ const int MAX_SCALE_PROBABILITIES_LOOP_ITERATIONS = 8;
+ const int PROBABILITY_VALUE_DECIMAL_PLACES = 3;
+ int loopIterations = 0;
+ do
+ {
+ if (probabilitySum > 1f)
+ {
+ float fixRatio = 1f / probabilitySum;
+ int countChanged = 0;
+ for (int pIdx = 0; pIdx < probabilitiesProperty.arraySize; ++pIdx)
+ {
+ if (allLocked)
+ {
+ countChanged++;
+ probabilitiesProperty.GetArrayElementAtIndex(pIdx).floatValue *= fixRatio;
+ }
+ else
+ {
+ if (pIdx == index || probabilityLockProperty.GetArrayElementAtIndex(pIdx).boolValue || probabilitiesProperty.GetArrayElementAtIndex(pIdx).floatValue == 0f)
+ continue;
+ countChanged++;
+ probabilitiesProperty.GetArrayElementAtIndex(pIdx).floatValue *= fixRatio;
+ }
+ }
+ if (countChanged == 0)
+ probabilitiesProperty.GetArrayElementAtIndex(index).floatValue -= probabilitySum - 1f;
+ probabilitiesProperty.GetArrayElementAtIndex(index).floatValue = (float)Math.Round(probabilitiesProperty.GetArrayElementAtIndex(index).floatValue, PROBABILITY_VALUE_DECIMAL_PLACES);
+ }
+ probabilitySum = 0f;
+ for (int pIdx = 0; pIdx < probabilitiesProperty.arraySize; ++pIdx)
+ probabilitySum += probabilitiesProperty.GetArrayElementAtIndex(pIdx).floatValue;
+ loopIterations++;
+ } while ((probabilitySum > 1f) && (loopIterations < MAX_SCALE_PROBABILITIES_LOOP_ITERATIONS));
+ }
+
+ if (isFocused)
+ objectLists[idx] = null;
+ if (isActive)
+ {
+ EditorGUILayout.Space();
+
+ RenderEventEditor(shadowProperty, triggerProperty, eventProperty, idx);
+ }
+ };
+ newList.onAddDropdownCallback = (Rect buttonRect, ReorderableList list) =>
+ {
+ GenericMenu menu = new GenericMenu();
+ SerializedProperty eventsList = triggerProperty.FindPropertyRelative("Events");
+ foreach (VRCSDK2.VRC_EventHandler.VrcEventType type in System.Enum.GetValues(typeof(VRCSDK2.VRC_EventHandler.VrcEventType)).Cast<VRCSDK2.VRC_EventHandler.VrcEventType>().Where(v => !hiddenEventTypes.Contains(v)).OrderBy(et => System.Enum.GetName(typeof(VRCSDK2.VRC_EventHandler.VrcEventType), et)))
+ {
+ menu.AddItem(new GUIContent("Basic Events/" + type.ToString()), false, (t) =>
+ {
+ eventsList.arraySize++;
+
+ SerializedProperty newEventProperty = eventsList.GetArrayElementAtIndex(eventsList.arraySize - 1);
+ newEventProperty.FindPropertyRelative("EventType").intValue = (int)(VRCSDK2.VRC_EventHandler.VrcEventType)t;
+ newEventProperty.FindPropertyRelative("ParameterObjects").arraySize = 0;
+ newEventProperty.FindPropertyRelative("ParameterInt").intValue = 0;
+ newEventProperty.FindPropertyRelative("ParameterFloat").floatValue = 0f;
+ newEventProperty.FindPropertyRelative("ParameterString").stringValue = null;
+
+ serializedObject.ApplyModifiedProperties();
+ }, type);
+ }
+ VRC.SDKBase.IVRCEventProvider[] providers = FindObjectsOfType<MonoBehaviour>().Where(b => b is VRC.SDKBase.IVRCEventProvider).Cast<VRC.SDKBase.IVRCEventProvider>().ToArray();
+ foreach (VRC.SDKBase.IVRCEventProvider provider in providers)
+ {
+ foreach (VRCSDK2.VRC_EventHandler.VrcEvent evt in provider.ProvideEvents())
+ {
+ string name = "Events from Scene/" + (provider as MonoBehaviour).name + "/" + evt.Name;
+ menu.AddItem(new GUIContent(name), false, (t) =>
+ {
+ eventsList.arraySize++;
+
+ VRCSDK2.VRC_EventHandler.VrcEvent e = (VRCSDK2.VRC_EventHandler.VrcEvent)t;
+
+ SerializedProperty newEventProperty = eventsList.GetArrayElementAtIndex(eventsList.arraySize - 1);
+ newEventProperty.FindPropertyRelative("Name").stringValue = e.Name;
+ newEventProperty.FindPropertyRelative("EventType").intValue = (int)e.EventType;
+ newEventProperty.FindPropertyRelative("ParameterInt").intValue = e.ParameterInt;
+ newEventProperty.FindPropertyRelative("ParameterFloat").floatValue = e.ParameterFloat;
+ newEventProperty.FindPropertyRelative("ParameterString").stringValue = e.ParameterString;
+ newEventProperty.FindPropertyRelative("ParameterObjects").arraySize = e.ParameterObjects.Length;
+ for (int obj_idx = 0; obj_idx < e.ParameterObjects.Length; ++obj_idx)
+ newEventProperty.FindPropertyRelative("ParameterObjects").GetArrayElementAtIndex(obj_idx).objectReferenceValue = e.ParameterObjects[obj_idx];
+
+#pragma warning disable CS0618 // Type or member is obsolete
+ newEventProperty.FindPropertyRelative("ParameterObject").objectReferenceValue = e.ParameterObject;
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ serializedObject.ApplyModifiedProperties();
+ }, evt);
+ }
+ }
+ menu.ShowAsContext();
+
+ eventLists = new ReorderableList[0];
+ objectLists = new ReorderableList[0];
+ relayLists = new ReorderableList[0];
+ };
+
+ eventLists[idx] = newList;
+ }
+
+ ReorderableList eventList = eventLists[idx];
+ eventList.DoLayoutList();
+ }
+
+ private void RenderDataStorage(SerializedProperty triggerProperty)
+ {
+ if (triggerProperty.serializedObject.targetObjects.Any(obj => (obj as VRCSDK2.VRC_Trigger).gameObject.GetComponent<VRCSDK2.VRC_DataStorage>() == null))
+ RenderHelpBox("Data Storage Triggers require a VRC_DataStorage Component.", MessageType.Warning);
+ else
+ {
+ SerializedProperty idxProperty = triggerProperty.FindPropertyRelative("DataElementIdx");
+ VRCSDK2.VRC_DataStorage ds = (target as VRCSDK2.VRC_Trigger).gameObject.GetComponent<VRCSDK2.VRC_DataStorage>();
+
+ if (ds.data == null)
+ {
+ ds.data = new VRCSDK2.VRC_DataStorage.VrcDataElement[0];
+ idxProperty.intValue = -1;
+ }
+
+ List<string> names = new List<string>();
+ names.Add("Any Data Element");
+ foreach (VRCSDK2.VRC_DataStorage.VrcDataElement element in ds.data)
+ names.Add(element.name);
+
+ int selectedIdx = idxProperty.intValue;
+ if (selectedIdx == -1)
+ selectedIdx = 0;
+ else
+ selectedIdx += 1;
+
+ selectedIdx = EditorGUILayout.Popup("Data Element", selectedIdx, names.ToArray());
+
+ if (selectedIdx == 0)
+ idxProperty.intValue = -1;
+ else
+ idxProperty.intValue = selectedIdx - 1;
+ }
+ }
+
+ private void RenderKey(SerializedProperty triggerProperty)
+ {
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("Key"));
+ }
+
+ private void RenderCollider(SerializedProperty triggerProperty)
+ {
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("TriggerIndividuals"));
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("Layers"));
+ }
+
+ private void RenderTimer(SerializedProperty triggerProperty)
+ {
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("Repeat"));
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("ResetOnEnable"));
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("LowPeriodTime"));
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("HighPeriodTime"));
+ }
+
+ private void RenderCustom(SerializedProperty triggerProperty)
+ {
+ SerializedProperty nameProperty = triggerProperty.FindPropertyRelative("Name");
+ EditorGUILayout.PropertyField(triggerProperty.FindPropertyRelative("Name"));
+
+ if (string.IsNullOrEmpty(nameProperty.stringValue))
+ nameProperty.stringValue = "Unnamed";
+ }
+
+ private void RenderRelay(SerializedProperty triggerProperty, int idx)
+ {
+ if (relayLists[idx] == null)
+ {
+ ReorderableList newList = new ReorderableList(serializedObject, triggerProperty.FindPropertyRelative("Others"), true, true, true, true);
+ newList.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, new GUIContent("Targets"));
+ newList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
+ {
+ SerializedProperty target = newList.serializedProperty.GetArrayElementAtIndex(index);
+
+ EditorGUI.PropertyField(rect, target, GUIContent.none);
+
+ target.serializedObject.ApplyModifiedProperties();
+ };
+ relayLists[idx] = newList;
+ }
+ relayLists[idx].DoLayoutList();
+ }
+
+ private void RenderEmpty(SerializedProperty triggerProperty)
+ {
+ }
+
+ private bool doesPropertyContainAnyNullReceivers(SerializedProperty objectsProperty)
+ {
+ bool containsNullReceivers = false;
+ if (objectsProperty.arraySize > 0)
+ {
+ for (int i = 0; i < objectsProperty.arraySize; i++)
+ {
+ SerializedProperty elem = objectsProperty.GetArrayElementAtIndex(i);
+ if (elem.objectReferenceValue == null) containsNullReceivers = true;
+ }
+ }
+ return containsNullReceivers;
+ }
+
+ private void RenderTargetGameObjectList(SerializedProperty objectsProperty, int idx, bool receiverRequired = true)
+ {
+ if (objectLists[idx] == null)
+ {
+ objectLists[idx] = new ReorderableList(objectsProperty.serializedObject, objectsProperty, true, true, true, true);
+ objectLists[idx].drawHeaderCallback = (Rect rect) =>
+ {
+ string infoString = "Receivers";
+ if (objectsProperty.arraySize == 0)
+ infoString = "Receivers: This GameObject";
+ EditorGUI.LabelField(rect, new GUIContent(infoString));
+
+ Event evt = Event.current;
+ if (!rect.Contains(evt.mousePosition))
+ return;
+
+ if (evt.type == EventType.DragUpdated)
+ DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
+ if (evt.type == EventType.DragPerform)
+ {
+ GameObject[] dragObjects = DragAndDrop.objectReferences.OfType<GameObject>().ToArray();
+ int startIndex = objectsProperty.arraySize;
+ objectsProperty.arraySize = objectsProperty.arraySize + dragObjects.Length;
+
+ for (int i = 0; i < dragObjects.Length; i++)
+ {
+ SerializedProperty newElem = objectsProperty.GetArrayElementAtIndex(startIndex + i);
+ newElem.objectReferenceValue = dragObjects[i];
+ }
+
+ DragAndDrop.AcceptDrag();
+ evt.Use();
+ }
+ };
+ objectLists[idx].drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
+ {
+ SerializedProperty target = objectLists[idx].serializedProperty.GetArrayElementAtIndex(index);
+ EditorGUI.PropertyField(rect, target, GUIContent.none);
+ target.serializedObject.ApplyModifiedProperties();
+ };
+ }
+ objectLists[idx].DoLayoutList();
+ if (objectsProperty.arraySize == 0)
+ RenderHelpBox("This trigger will target the GameObject it's on, because the receivers list is empty.", MessageType.Error);
+ else if (receiverRequired && doesPropertyContainAnyNullReceivers(objectsProperty))
+ RenderHelpBox("Trigger with no object set will be ignored!", MessageType.Info);
+ }
+
+ private void RenderTargetComponentList<T>(SerializedProperty objectsProperty, int idx, string label = "Receivers") where T : Component
+ {
+ if (objectLists[idx] == null)
+ {
+ objectLists[idx] = new ReorderableList(objectsProperty.serializedObject, objectsProperty, true, true, true, true);
+ objectLists[idx].drawHeaderCallback = (Rect rect) =>
+ {
+ string infoString = label;
+ if (objectsProperty.arraySize == 0)
+ infoString = label + ": This " + typeof(T).Name;
+ EditorGUI.LabelField(rect, new GUIContent(infoString));
+
+ Event evt = Event.current;
+ if (!rect.Contains(evt.mousePosition))
+ return;
+
+ if (evt.type == EventType.DragUpdated)
+ DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
+ if (evt.type == EventType.DragPerform)
+ {
+ GameObject[] dragObjects = DragAndDrop.objectReferences.OfType<GameObject>().ToArray();
+ int startIndex = objectsProperty.arraySize;
+ objectsProperty.arraySize = objectsProperty.arraySize + dragObjects.Length;
+
+ for (int i = 0; i < dragObjects.Length; i++)
+ {
+ SerializedProperty newElem = objectsProperty.GetArrayElementAtIndex(startIndex + i);
+ newElem.objectReferenceValue = dragObjects[i];
+ }
+
+ DragAndDrop.AcceptDrag();
+ evt.Use();
+ }
+ };
+ objectLists[idx].drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
+ {
+ SerializedProperty target = objectLists[idx].serializedProperty.GetArrayElementAtIndex(index);
+
+ T current = null;
+ if (target.objectReferenceValue != null)
+ current = (target.objectReferenceValue as GameObject).GetComponent<T>();
+
+ current = EditorGUI.ObjectField(rect, current, typeof(T), true) as T;
+ target.objectReferenceValue = current == null ? null : current.gameObject;
+ target.serializedObject.ApplyModifiedProperties();
+ };
+ }
+ objectLists[idx].DoLayoutList();
+ if (objectsProperty.arraySize == 0)
+ RenderHelpBox("This trigger will target the GameObject it's on, because the receivers list is empty.", MessageType.Error);
+ else if (doesPropertyContainAnyNullReceivers(objectsProperty))
+ RenderHelpBox("Trigger with no object set will be ignored!", MessageType.Info);
+ }
+
+ public void RenderEventEditor(SerializedProperty shadowProperty, SerializedProperty triggerProperty, SerializedProperty eventProperty, int triggerIdx)
+ {
+ SerializedProperty eventTypeProperty = eventProperty.FindPropertyRelative("EventType");
+ SerializedProperty parameterObjectProperty = eventProperty.FindPropertyRelative("ParameterObject");
+ SerializedProperty parameterObjectsProperty = eventProperty.FindPropertyRelative("ParameterObjects");
+ SerializedProperty parameterStringProperty = eventProperty.FindPropertyRelative("ParameterString");
+ SerializedProperty parameterBoolOpProperty = eventProperty.FindPropertyRelative("ParameterBoolOp");
+ SerializedProperty parameterFloatProperty = eventProperty.FindPropertyRelative("ParameterFloat");
+ SerializedProperty parameterIntProperty = eventProperty.FindPropertyRelative("ParameterInt");
+ SerializedProperty parameterBytesProperty = eventProperty.FindPropertyRelative("ParameterBytes");
+
+ if (parameterObjectProperty.objectReferenceValue != null && parameterObjectsProperty.arraySize == 0)
+ {
+ parameterObjectsProperty.arraySize = 1;
+ parameterObjectsProperty.GetArrayElementAtIndex(0).objectReferenceValue = parameterObjectProperty.objectReferenceValue;
+ }
+ parameterObjectProperty.objectReferenceValue = null;
+
+ switch ((VRCSDK2.VRC_EventHandler.VrcEventType)eventTypeProperty.intValue)
+ {
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationBool:
+ {
+ RenderTargetComponentList<Animator>(parameterObjectsProperty, triggerIdx);
+
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Variable"));
+ RenderPropertyEditor(shadowProperty, parameterBoolOpProperty, new GUIContent("Operation"), true);
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationFloat:
+ {
+ RenderTargetComponentList<Animator>(parameterObjectsProperty, triggerIdx);
+
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Variable"));
+ RenderPropertyEditor(shadowProperty, parameterFloatProperty, new GUIContent("Value"));
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationInt:
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationIntAdd:
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationIntDivide:
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationIntMultiply:
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationIntSubtract:
+ {
+ RenderTargetComponentList<Animator>(parameterObjectsProperty, triggerIdx);
+
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Variable"));
+ RenderPropertyEditor(shadowProperty, parameterIntProperty, new GUIContent("Value"));
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AnimationTrigger:
+ {
+ RenderTargetComponentList<Animator>(parameterObjectsProperty, triggerIdx);
+
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Trigger"));
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.PlayAnimation:
+ {
+ RenderTargetComponentList<Animation>(parameterObjectsProperty, triggerIdx);
+
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Clip"));
+
+ for (int idx = 0; idx < parameterObjectsProperty.arraySize; ++idx)
+ {
+ GameObject obj = parameterObjectsProperty.GetArrayElementAtIndex(idx).objectReferenceValue as GameObject;
+ Animation anim = obj == null ? null : obj.GetComponent<Animation>();
+ if (anim != null && anim.GetClip(parameterStringProperty.stringValue) == null)
+ {
+ RenderHelpBox("Could not locate " + parameterStringProperty.stringValue + " on " + obj.name + "; is it legacy?", MessageType.Error);
+ break;
+ }
+ }
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AudioTrigger:
+ {
+ RenderTargetComponentList<AudioSource>(parameterObjectsProperty, triggerIdx);
+
+ List<string> clipNames = new List<string>();
+ if (parameterObjectsProperty.arraySize > 0)
+ {
+ int idx = 0;
+ for (; idx < parameterObjectsProperty.arraySize; ++idx)
+ {
+ SerializedProperty prop = parameterObjectsProperty.GetArrayElementAtIndex(0);
+ GameObject obj = prop.objectReferenceValue != null ? prop.objectReferenceValue as GameObject : null;
+ if (obj != null)
+ {
+ foreach (AudioSource source in obj.GetComponents<AudioSource>())
+ if (source.clip != null && !string.IsNullOrEmpty(source.clip.name))
+ clipNames.Add(source.clip.name);
+ break;
+ }
+ }
+ for (; idx < parameterObjectsProperty.arraySize; ++idx)
+ {
+ SerializedProperty prop = parameterObjectsProperty.GetArrayElementAtIndex(0);
+ GameObject obj = prop.objectReferenceValue != null ? prop.objectReferenceValue as GameObject : null;
+ if (obj != null)
+ {
+ List<string> thisClipNames = new List<string>();
+ foreach (AudioSource source in obj.GetComponents<AudioSource>())
+ if (source.clip != null && !string.IsNullOrEmpty(source.clip.name))
+ thisClipNames.Add(source.clip.name);
+ clipNames.RemoveAll(s => thisClipNames.Contains(s) == false);
+ }
+ }
+ }
+
+ clipNames.Insert(0, "");
+ int selectedIdx;
+ for (selectedIdx = clipNames.Count - 1; selectedIdx > 0; --selectedIdx)
+ if (parameterStringProperty.stringValue == clipNames[selectedIdx])
+ break;
+
+ parameterStringProperty.stringValue = clipNames[EditorGUILayout.Popup("Clip", selectedIdx, clipNames.ToArray())];
+ break;
+ }
+#pragma warning disable CS0618 // Type or member is obsolete
+ case VRCSDK2.VRC_EventHandler.VrcEventType.MeshVisibility:
+#pragma warning restore CS0618 // Type or member is obsolete
+ {
+ RenderTargetComponentList<Renderer>(parameterObjectsProperty, triggerIdx);
+ RenderPropertyEditor(shadowProperty, parameterBoolOpProperty, new GUIContent("Operation"), true);
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.RunConsoleCommand:
+ {
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Command"));
+ break;
+ }
+#pragma warning disable CS0618 // Type or member is obsolete
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SendMessage:
+#pragma warning restore CS0618 // Type or member is obsolete
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+ if (parameterObjectsProperty.arraySize > 0)
+ RenderMethodSelector(eventProperty);
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetGameObjectActive:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+ RenderPropertyEditor(shadowProperty, parameterBoolOpProperty, new GUIContent("Operation"), true);
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetParticlePlaying:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+ RenderPropertyEditor(shadowProperty, parameterBoolOpProperty, new GUIContent("Operation"), true);
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.TeleportPlayer:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+ RenderPropertyEditor(shadowProperty, parameterBoolOpProperty, new GUIContent("Align Room To Destination"), true);
+ parameterIntProperty.intValue = EditorGUILayout.Toggle("Lerp On Remote Clients", (parameterIntProperty.intValue != 0)) ? 1 : 0;
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelURI:
+ {
+ RenderTargetComponentList<VRCSDK2.VRC_WebPanel>(parameterObjectsProperty, triggerIdx);
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("URI"));
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetWebPanelVolume:
+ {
+ RenderTargetComponentList<VRCSDK2.VRC_WebPanel>(parameterObjectsProperty, triggerIdx);
+ parameterFloatProperty.floatValue = EditorGUILayout.Slider("Volume", parameterFloatProperty.floatValue, 0f, 1f);
+ break;
+ }
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SendRPC:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+
+ if (parameterObjectsProperty.arraySize > 0)
+ {
+ RenderMethodSelector(eventProperty);
+ RenderRPCParameterEditor(eventProperty);
+ }
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.ActivateCustomTrigger:
+ {
+ RenderTargetComponentList<VRCSDK2.VRC_Trigger>(parameterObjectsProperty, triggerIdx);
+
+ VRC_EditorTools.CustomTriggerPopup("Name", parameterObjectsProperty, parameterStringProperty);
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SpawnObject:
+ {
+ VRCSDK2.VRC_SceneDescriptor scene = FindObjectOfType<VRCSDK2.VRC_SceneDescriptor>();
+
+ string path = parameterStringProperty.stringValue;
+ GameObject found = scene != null ? scene.DynamicPrefabs.FirstOrDefault(p => AssetDatabase.GetAssetOrScenePath(p) == path) : null;
+ found = found == null ? AssetDatabase.LoadAssetAtPath<GameObject>(path) : found;
+ GameObject newFound = EditorGUILayout.ObjectField("Prefab", found, typeof(GameObject), false) as GameObject;
+ parameterStringProperty.stringValue = newFound == null ? null : AssetDatabase.GetAssetOrScenePath(newFound);
+
+ RenderTargetComponentList<Transform>(parameterObjectsProperty, triggerIdx, "Locations");
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.DestroyObject:
+ {
+ SerializedProperty broadcastTypeProperty = triggerProperty.FindPropertyRelative("BroadcastType");
+ VRCSDK2.VRC_EventHandler.VrcBroadcastType broadcast = (VRCSDK2.VRC_EventHandler.VrcBroadcastType)broadcastTypeProperty.intValue;
+ if (broadcast != VRCSDK2.VRC_EventHandler.VrcBroadcastType.Always && broadcast != VRCSDK2.VRC_EventHandler.VrcBroadcastType.AlwaysUnbuffered && broadcast != VRCSDK2.VRC_EventHandler.VrcBroadcastType.AlwaysBufferOne)
+ RenderHelpBox("Not all clients will destroy the object.", MessageType.Warning);
+
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetLayer:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+ parameterIntProperty.intValue = (int)EditorGUILayout.LayerField("Layer", parameterIntProperty.intValue);
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetMaterial:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+
+ VRCSDK2.VRC_SceneDescriptor scene = FindObjectOfType<VRCSDK2.VRC_SceneDescriptor>();
+
+ string path = parameterStringProperty.stringValue;
+ Material found = scene != null ? scene.DynamicMaterials.FirstOrDefault(p => AssetDatabase.GetAssetOrScenePath(p) == path) : null;
+ found = found == null ? AssetDatabase.LoadAssetAtPath<Material>(path) : found;
+ Material newFound = EditorGUILayout.ObjectField("Material", found, typeof(Material), false) as Material;
+ parameterStringProperty.stringValue = newFound == null ? null : AssetDatabase.GetAssetOrScenePath(newFound);
+
+ if (scene != null && found != newFound)
+ {
+ scene.DynamicMaterials.Add(newFound);
+ scene.DynamicMaterials.Remove(found);
+ }
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AddDamage:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx, false);
+ RenderPropertyEditor(shadowProperty, parameterFloatProperty, new GUIContent("Damage"));
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AddHealth:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx, false);
+ RenderPropertyEditor(shadowProperty, parameterFloatProperty, new GUIContent("Health"));
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetComponentActive:
+ {
+ RenderTargetGameObjectList(parameterObjectsProperty, triggerIdx);
+ if (RenderTargetComponentEditor(parameterStringProperty, parameterObjectsProperty, triggerIdx))
+ RenderPropertyEditor(shadowProperty, parameterBoolOpProperty, new GUIContent("Enable"), true);
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AddVelocity:
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetVelocity:
+ {
+ RenderTargetComponentList<Rigidbody>(parameterObjectsProperty, triggerIdx);
+ RenderVector3andSpacePropertyEditor(parameterBytesProperty, new GUIContent("Velocity"));
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AddAngularVelocity:
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetAngularVelocity:
+ {
+ RenderTargetComponentList<Rigidbody>(parameterObjectsProperty, triggerIdx);
+ RenderVector3andSpacePropertyEditor(parameterBytesProperty, new GUIContent("Angular Velocity"));
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.AddForce:
+ {
+ RenderTargetComponentList<Rigidbody>(parameterObjectsProperty, triggerIdx);
+ RenderVector3andSpacePropertyEditor(parameterBytesProperty, new GUIContent("Force"));
+ }
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcEventType.SetUIText:
+ {
+ RenderTargetComponentList<Text>(parameterObjectsProperty, triggerIdx);
+ RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Text"));
+ }
+ break;
+
+#if UDON
+ case VRCSDK2.VRC_EventHandler.VrcEventType.CallUdonMethod:
+ //{
+ // RenderTargetComponentList<VRC.Udon.UdonBehaviour>(parameterObjectsProperty, triggerIdx);
+ // RenderPropertyEditor(shadowProperty, parameterStringProperty, new GUIContent("Method Name"));
+ //}
+ break;
+#endif
+ default:
+ RenderHelpBox("Unsupported event type", MessageType.Error);
+ break;
+ }
+ }
+
+ private void RenderVector3andSpacePropertyEditor(SerializedProperty propertyBytes, GUIContent label)
+ {
+ object[] parameters = null;
+ parameters = VRC.SDKBase.VRC_Serialization.ParameterDecoder(VRC_EditorTools.ReadBytesFromProperty(propertyBytes));
+ if (parameters.Length == 0)
+ parameters = new object[1] { new Vector4() };
+
+ EditorGUI.BeginChangeCheck();
+ Vector3 vec3Field = EditorGUILayout.Vector3Field(label, new Vector3(((Vector4)parameters[0]).x, ((Vector4)parameters[0]).y, ((Vector4)parameters[0]).z));
+ bool spaceField = EditorGUILayout.Toggle("Use World Space", ((Vector4)parameters[0]).w > .5f ? true : false);
+ parameters[0] = new Vector4(vec3Field.x, vec3Field.y, vec3Field.z, Convert.ToSingle(spaceField));
+ if (EditorGUI.EndChangeCheck())
+ {
+ VRC_EditorTools.WriteBytesToProperty(propertyBytes, VRC.SDKBase.VRC_Serialization.ParameterEncoder(parameters));
+ }
+ }
+
+ private void RenderVector3PropertyEditor(SerializedProperty propertyBytes, GUIContent label)
+ {
+ object[] parameters = null;
+ parameters = VRC.SDKBase.VRC_Serialization.ParameterDecoder(VRC_EditorTools.ReadBytesFromProperty(propertyBytes));
+ if (parameters.Length == 0)
+ parameters = new object[1] { new Vector3() };
+
+ EditorGUI.BeginChangeCheck();
+ parameters[0] = EditorGUILayout.Vector3Field(label, (Vector3)parameters[0]);
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ VRC_EditorTools.WriteBytesToProperty(propertyBytes, VRC.SDKBase.VRC_Serialization.ParameterEncoder(parameters));
+ }
+ }
+
+ bool RenderTargetComponentEditor(SerializedProperty componentNameProperty, SerializedProperty objectsProperty, int triggerIdx)
+ {
+ if (!objectsProperty.isArray || objectsProperty.arraySize == 0)
+ return false;
+
+ HashSet<Type> behaviours = new HashSet<Type>();
+ bool isFirst = true;
+ for (int objIdx = 0; objIdx < objectsProperty.arraySize; ++objIdx)
+ {
+ if (objectsProperty.GetArrayElementAtIndex(objIdx) == null || objectsProperty.GetArrayElementAtIndex(objIdx).objectReferenceValue == null || !(objectsProperty.GetArrayElementAtIndex(objIdx).objectReferenceValue is GameObject))
+ continue;
+
+ if (isFirst)
+ {
+ foreach (Component component in (objectsProperty.GetArrayElementAtIndex(0).objectReferenceValue as GameObject).GetComponents(typeof(Component)))
+ {
+ Type t = component.GetType();
+ if (t.GetProperty("enabled") != null)
+ behaviours.Add(component.GetType());
+ }
+ isFirst = false;
+ }
+ else
+ {
+ HashSet<Type> thisBehaviours = new HashSet<Type>();
+ foreach (Component component in (objectsProperty.GetArrayElementAtIndex(objIdx).objectReferenceValue as GameObject).GetComponents(typeof(Component)))
+ {
+ Type t = component.GetType();
+ if (t.GetProperty("enabled") != null)
+ thisBehaviours.Add(component.GetType());
+ }
+ behaviours.RemoveWhere(s => thisBehaviours.Contains(s) == false);
+ }
+ }
+
+ if (behaviours.Count == 0)
+ return false;
+
+ Type[] types = behaviours.ToArray();
+ string[] options = behaviours.Select(t => t.FullName).ToArray();
+ int selectedIdx = 0;
+ for (int typeIdx = 0; typeIdx < types.Length; ++typeIdx)
+ if (types[typeIdx].FullName == componentNameProperty.stringValue)
+ {
+ selectedIdx = typeIdx;
+ break;
+ }
+
+ selectedIdx = EditorGUILayout.Popup("Component", selectedIdx, options);
+ componentNameProperty.stringValue = types[selectedIdx].FullName;
+
+ return true;
+ }
+
+ void RenderRPCParameterEditor(SerializedProperty eventProperty)
+ {
+ EditorGUI.BeginChangeCheck();
+
+ SerializedProperty parameterIntProperty = eventProperty.FindPropertyRelative("ParameterInt");
+ SerializedProperty parameterObjectsProperty = eventProperty.FindPropertyRelative("ParameterObjects");
+ SerializedProperty parameterStringProperty = eventProperty.FindPropertyRelative("ParameterString");
+ SerializedProperty parameterBytesProperty = eventProperty.FindPropertyRelative("ParameterBytes");
+
+ if (parameterIntProperty.intValue == -1)
+ parameterIntProperty.intValue = (int)(VRCSDK2.VRC_EventHandler.VrcTargetType.All);
+
+ parameterIntProperty.intValue = (int)VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_EventHandler.VrcTargetType>("Targets", (VRCSDK2.VRC_EventHandler.VrcTargetType)parameterIntProperty.intValue, e => e != VRCSDK2.VRC_EventHandler.VrcTargetType.TargetPlayer);
+
+ string message = null;
+ switch ((VRCSDK2.VRC_EventHandler.VrcTargetType)parameterIntProperty.intValue)
+ {
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.All:
+ message = "Will execute on all clients, except for those that join later.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.AllBuffered:
+ message = "Will execute on all clients, including those that join later.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.Local:
+ message = "Will execute for the instigator only.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.Master:
+ message = "Will execute on the Master.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.Others:
+ message = "Will execute for others but not locally, except for those that join later.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.OthersBuffered:
+ message = "Will execute for others but not locally, including those that join later.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.Owner:
+ message = "Will execute on the Owner.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.AllBufferOne:
+ message = "Will execute on all clients, and only the most recent is executed for those that join later.";
+ break;
+ case VRCSDK2.VRC_EventHandler.VrcTargetType.OthersBufferOne:
+ message = "Will execute for others but not locally, and only the most recent is executed for those that join later.";
+ break;
+ }
+ if (message != null)
+ RenderHelpBox(message, MessageType.Info);
+
+ Dictionary<string, List<MethodInfo>> methods = VRC_EditorTools.GetSharedAccessibleMethodsOnGameObjects(parameterObjectsProperty);
+ if (methods.Count == 0)
+ {
+ RenderHelpBox("No applicable methods found.", MessageType.Error);
+ return;
+ }
+
+ List<MethodInfo> methodInfos = methods.Values.Aggregate(new List<MethodInfo>(), (acc, lst) => { acc.AddRange(lst); return acc; });
+
+ MethodInfo info = methodInfos.FirstOrDefault(m => m.Name == parameterStringProperty.stringValue);
+ if (info == null)
+ return;
+
+ ParameterInfo[] paramInfo = info.GetParameters();
+
+ // Editor-only
+ foreach (var p in paramInfo)
+ if (p.ParameterType.Namespace.StartsWith("VRCSDK2"))
+ VRC.SDKBase.VRC_Serialization.RegisterType(p.ParameterType);
+
+ object[] parameters = null;
+ if (rpcByteCache.ContainsKey(eventProperty.propertyPath))
+ parameters = rpcByteCache[eventProperty.propertyPath];
+ else
+ {
+ parameters = VRC.SDKBase.VRC_Serialization.ParameterDecoder(VRC_EditorTools.ReadBytesFromProperty(parameterBytesProperty));
+ rpcByteCache.Add(eventProperty.propertyPath, parameters);
+ }
+
+ if (parameters == null)
+ parameters = new object[paramInfo.Length];
+ if (parameters.Length != paramInfo.Length)
+ Array.Resize(ref parameters, paramInfo.Length);
+
+ EditorGUI.BeginChangeCheck();
+
+ bool finalParamIsPlayer = false;
+
+ for (int idx = 0; idx < parameters.Length; ++idx)
+ {
+ Type paramType = paramInfo[idx].ParameterType;
+ if (paramType == typeof(Color))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = Color.black;
+ parameters[idx] = EditorGUILayout.ColorField(paramInfo[idx].Name, (Color)parameters[idx]);
+ }
+ else if (paramType == typeof(bool))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = false;
+ parameters[idx] = EditorGUILayout.Toggle(paramInfo[idx].Name, (bool)parameters[idx]);
+ }
+ else if (paramType.IsEnum)
+ {
+ // make an array of strings of the enum values
+ var values = Enum.GetValues(paramType);
+ string[] itemStrings = new string[values.Length];
+ int i = 0;
+ foreach (var item in Enum.GetValues(paramType))
+ {
+ itemStrings[i++] = item.ToString();
+ }
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = Enum.Parse(paramType, itemStrings[0]);
+ parameters[idx] = Enum.Parse(paramType, itemStrings[EditorGUILayout.Popup(paramInfo[idx].Name, (int)parameters[idx], itemStrings)]);
+ }
+ else if (paramType == typeof(double))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = 0d;
+ parameters[idx] = EditorGUILayout.DoubleField(paramInfo[idx].Name, (double)parameters[idx]);
+ }
+ else if (paramType == typeof(float))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = 0f;
+ parameters[idx] = EditorGUILayout.FloatField(paramInfo[idx].Name, (float)parameters[idx]);
+ }
+ else if (paramType == typeof(int))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = 0;
+ parameters[idx] = EditorGUILayout.IntField(paramInfo[idx].Name, (int)parameters[idx]);
+ }
+ else if (typeof(VRC.SDKBase.VRCPlayerApi).IsAssignableFrom(paramType))
+ {
+ if (idx == parameters.Length - 1)
+ finalParamIsPlayer = true;
+ parameters[idx] = null;
+ }
+ else if (paramType == typeof(long))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = 0;
+ parameters[idx] = EditorGUILayout.LongField(paramInfo[idx].Name, (long)parameters[idx]);
+ }
+ else if (paramType == typeof(UnityEngine.Rect))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = new Rect();
+ parameters[idx] = EditorGUILayout.RectField(paramInfo[idx].Name, (UnityEngine.Rect)parameters[idx]);
+ }
+ else if (paramType == typeof(string))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = "";
+ parameters[idx] = EditorGUILayout.TextField(paramInfo[idx].Name, (string)parameters[idx]);
+ }
+ else if (paramType == typeof(Vector2))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = new Vector2();
+ parameters[idx] = EditorGUILayout.Vector2Field(paramInfo[idx].Name, (Vector2)parameters[idx]);
+ }
+ else if (paramType == typeof(Vector3))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = new Vector3();
+ parameters[idx] = EditorGUILayout.Vector3Field(paramInfo[idx].Name, (Vector3)parameters[idx]);
+ }
+ else if (paramType == typeof(Vector4))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = new Vector4();
+ parameters[idx] = EditorGUILayout.Vector4Field(paramInfo[idx].Name, (Vector4)parameters[idx]);
+ }
+ else if (paramType == typeof(Quaternion))
+ {
+ if (parameters[idx] == null || parameters[idx].GetType() != paramType)
+ parameters[idx] = new Quaternion();
+ parameters[idx] = Quaternion.Euler(EditorGUILayout.Vector3Field(paramInfo[idx].Name, ((Quaternion)parameters[idx]).eulerAngles));
+ }
+ else if (paramType == typeof(UnityEngine.Object) || paramType.IsSubclassOf(typeof(UnityEngine.Object)))
+ {
+ if (parameters[idx] != null && parameters[idx].GetType() != paramType)
+ parameters[idx] = null;
+ parameters[idx] = EditorGUILayout.ObjectField(paramInfo[idx].Name, (UnityEngine.Object)parameters[idx], paramType, true);
+ }
+ else
+ EditorGUILayout.LabelField("Unable to handle " + paramType.Name, EditorStyles.boldLabel);
+ }
+
+ if (finalParamIsPlayer)
+ Array.Resize(ref parameters, parameters.Length - 1);
+
+ if (EditorGUI.EndChangeCheck())
+ {
+ VRC_EditorTools.WriteBytesToProperty(parameterBytesProperty, VRC.SDKBase.VRC_Serialization.ParameterEncoder(parameters));
+ rpcByteCache[eventProperty.propertyPath] = parameters;
+ }
+ }
+
+ void RenderMethodSelector(SerializedProperty eventProperty)
+ {
+ SerializedProperty parameterObjectsProperty = eventProperty.FindPropertyRelative("ParameterObjects");
+ SerializedProperty parameterStringProperty = eventProperty.FindPropertyRelative("ParameterString");
+ SerializedProperty parameterBytesProperty = eventProperty.FindPropertyRelative("ParameterBytes");
+
+ Dictionary<string, List<MethodInfo>> methods = VRC_EditorTools.GetSharedAccessibleMethodsOnGameObjects(parameterObjectsProperty);
+ if (methods.Count == 0)
+ return;
+
+ List<string> combined = methods
+ .Select(pair => pair.Value.Select(s => pair.Key + "." + s.Name))
+ .Aggregate((a, b) =>
+ {
+ var v = new List<string>();
+ v.AddRange(a);
+ v.AddRange(b);
+ return v;
+ }).ToList();
+ combined.Insert(0, "Custom Method");
+
+ int currentIndex = string.IsNullOrEmpty(parameterStringProperty.stringValue) ? 0 : combined.FindIndex(s =>
+ {
+ var split = s.Split('.');
+ return split.Length > 1 && s.Split('.')[1] == parameterStringProperty.stringValue;
+ });
+ if (currentIndex < 0 || currentIndex >= combined.Count)
+ currentIndex = 0;
+
+ int newIndex = EditorGUILayout.Popup("Method", currentIndex, combined.ToArray());
+ if (newIndex != currentIndex)
+ {
+ parameterStringProperty.stringValue = "";
+ parameterBytesProperty.arraySize = 0;
+ }
+ currentIndex = newIndex;
+
+ if (currentIndex == 0)
+ EditorGUILayout.PropertyField(parameterStringProperty, new GUIContent("Custom Method"));
+ else
+ parameterStringProperty.stringValue = combined[currentIndex].Split('.')[1];
+ }
+
+ private void RenderPropertyEditor(SerializedProperty shadowProperty, SerializedProperty property, GUIContent label, bool isBoolOp = false)
+ {
+ VRCSDK2.VRC_DataStorage ds = (target as VRCSDK2.VRC_Trigger).gameObject.GetComponent<VRCSDK2.VRC_DataStorage>();
+ if (ds != null && ds.data != null && ds.data.Length != 0 && shadowProperty != null)
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel(label);
+
+ bool renderField = false;
+ switch (property.propertyType)
+ {
+ case SerializedPropertyType.Boolean:
+ {
+ SerializedProperty prop = shadowProperty.FindPropertyRelative("ParameterBoolOp");
+ List<string> vals = ds.data.Where(el => el.type == VRCSDK2.VRC_DataStorage.VrcDataType.Bool).Select(el => el.name).ToList();
+ renderField = !ListPopup(vals, prop);
+ }
+ break;
+ case SerializedPropertyType.Float:
+ {
+ SerializedProperty prop = shadowProperty.FindPropertyRelative("ParameterFloat");
+ List<string> vals = ds.data.Where(el => el.type == VRCSDK2.VRC_DataStorage.VrcDataType.Float).Select(el => el.name).ToList();
+ renderField = !ListPopup(vals, prop);
+ }
+ break;
+ case SerializedPropertyType.Integer:
+ {
+ SerializedProperty prop = shadowProperty.FindPropertyRelative("ParameterInt");
+ List<string> vals = ds.data.Where(el => el.type == VRCSDK2.VRC_DataStorage.VrcDataType.Int).Select(el => el.name).ToList();
+ renderField = !ListPopup(vals, prop);
+ }
+ break;
+ case SerializedPropertyType.String:
+ {
+ SerializedProperty prop = shadowProperty.FindPropertyRelative("ParameterString");
+ List<string> vals = ds.data.Where(el => el.type == VRCSDK2.VRC_DataStorage.VrcDataType.String).Select(el => el.name).ToList();
+ renderField = !ListPopup(vals, prop);
+ }
+ break;
+ default:
+ {
+ renderField = true;
+ }
+ break;
+ }
+
+ if (renderField)
+ EditorGUILayout.PropertyField(property, GUIContent.none);
+ EditorGUILayout.EndHorizontal();
+ }
+ else
+ {
+ if (isBoolOp)
+ VRC_EditorTools.FilteredEnumPopup<VRCSDK2.VRC_EventHandler.VrcBooleanOp>(label.text, property, s => s != VRCSDK2.VRC_EventHandler.VrcBooleanOp.Unused);
+ else
+ EditorGUILayout.PropertyField(property, label);
+ return;
+ }
+ }
+
+ private bool ListPopup(List<string> vals, SerializedProperty prop, bool custom = true)
+ {
+ if (vals.Count == 0)
+ return false;
+
+ if (custom)
+ vals.Insert(0, "Custom");
+
+ int selectedIdx = prop.stringValue == null ? 0 : vals.IndexOf(prop.stringValue);
+ if (selectedIdx < 0 || selectedIdx > vals.Count)
+ selectedIdx = 0;
+
+ int idx = EditorGUILayout.Popup(selectedIdx, vals.ToArray());
+ if (idx == 0 && custom)
+ {
+ prop.stringValue = null;
+ return false;
+ }
+ else
+ {
+ prop.stringValue = vals[idx];
+ return true;
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs.meta
new file mode 100644
index 00000000..f108aeb7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_TriggerEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 3aecd666943878944a811acb9db2ace7
+timeCreated: 1474315179
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs
new file mode 100644
index 00000000..3f646e0a
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs
@@ -0,0 +1,215 @@
+#if VRC_SDK_VRCSDK2 && UNITY_EDITOR
+using System.IO;
+using UnityEditor;
+using UnityEngine;
+using UnityEditor.Build;
+using System;
+using System.Linq;
+using VRC.SDKBase.Editor;
+
+namespace VRCSDK2
+{
+ [CustomEditor(typeof(VRCSDK2.VRC_WebPanel))]
+ public class VRC_WebPanelEditor : UnityEditor.Editor
+ {
+ private void InspectorField(string propertyName, string humanName)
+ {
+ SerializedProperty propertyField = serializedObject.FindProperty(propertyName);
+ EditorGUILayout.PropertyField(propertyField, new GUIContent(humanName), true);
+ }
+
+ bool showFiles = false;
+ System.Collections.Generic.List<string> directories = null;
+ System.Collections.Generic.List<string> files = null;
+
+ public override void OnInspectorGUI()
+ {
+ serializedObject.Update();
+ EditorGUI.BeginChangeCheck();
+
+ EditorGUILayout.BeginVertical();
+
+ EditorGUILayout.HelpBox("Do not play any videos with Web Panels, use VRC_SyncVideoPlayer instead!", MessageType.Error);
+
+ EditorGUILayout.Space();
+
+ InspectorField("proximity", "Proximity for Interactivity");
+ EditorGUILayout.Space();
+
+ VRCSDK2.VRC_WebPanel web = (VRCSDK2.VRC_WebPanel)target;
+
+ if (Application.isPlaying)
+ {
+ InspectorField("webRoot", "Web Root");
+ InspectorField("defaultUrl", "URI");
+
+ showFiles = web.webData != null && EditorGUILayout.Foldout(showFiles, web.webData.Count.ToString() + " files imported");
+ if (showFiles)
+ foreach (var file in web.webData)
+ {
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel(file.path);
+ EditorGUILayout.LabelField(file.data.Length.ToString());
+ EditorGUILayout.EndHorizontal();
+ }
+ }
+ else
+ {
+ SerializedProperty webRoot = serializedObject.FindProperty("webRoot");
+ RenderDirectoryList(serializedObject, "webRoot", "Path To Web Content");
+
+ if (string.IsNullOrEmpty(webRoot.stringValue))
+ {
+ InspectorField("defaultUrl", "Start URI");
+ }
+ else
+ {
+ RenderWebRootSelector(serializedObject, "defaultUrl", "Start Page");
+
+ if (VRCSettings.DisplayHelpBoxes)
+ {
+ EditorGUILayout.HelpBox("Javascript API bindings are called with engine.call('methodName', ...), which returns a promise-like object.", MessageType.Info);
+ EditorGUILayout.HelpBox("Javascript may call ListBindings() to discover available API bindings.", MessageType.Info);
+ EditorGUILayout.HelpBox("Javascript may listen for the 'onBindingsReady' event to execute script when the page is fully loaded and API bindings are available.", MessageType.Info);
+ }
+ }
+ }
+
+ EditorGUILayout.Space();
+
+ InspectorField("cookiesEnabled", "Enable Cookies");
+
+ InspectorField("interactive", "Is Interactive");
+
+ InspectorField("localOnly", "Only Visible Locally");
+
+ if (!web.localOnly)
+ {
+ InspectorField("syncURI", "Synchronize URI");
+ InspectorField("syncInput", "Synchronize Mouse Position");
+ }
+
+ InspectorField("transparent", "Transparent Background");
+
+ InspectorField("autoFormSubmit", "Input should Submit Forms");
+
+ EditorGUILayout.Space();
+
+ InspectorField("station", "Interaction Station");
+ EditorGUILayout.Space();
+
+ InspectorField("cursor", "Mouse Cursor Object");
+
+ EditorGUILayout.Space();
+
+ InspectorField("resolutionWidth", "Resolution Width");
+ InspectorField("resolutionHeight", "Resolution Height");
+ InspectorField("displayRegion", "Display Region");
+
+ EditorGUILayout.Space();
+
+ InspectorField("extraVideoScreens", "Duplicate Screens");
+
+ EditorGUILayout.EndVertical();
+
+ if (EditorGUI.EndChangeCheck())
+ serializedObject.ApplyModifiedProperties();
+ }
+
+ private void AddSubDirectories(ref System.Collections.Generic.List<string> l, string root)
+ {
+ if (!Directory.Exists(root))
+ {
+ return;
+ }
+
+ if (!root.StartsWith(Application.dataPath + Path.DirectorySeparatorChar + "VRCSDK")
+ || root == Application.dataPath + Path.DirectorySeparatorChar + "VRCSDK" + Path.DirectorySeparatorChar + "Examples" + Path.DirectorySeparatorChar + "Sample Assets" + Path.DirectorySeparatorChar + "WebRoot")
+ l.Add(root.Substring(Application.dataPath.Length));
+
+ string[] subdirectories = Directory.GetDirectories(root);
+ foreach (string dir in subdirectories)
+ AddSubDirectories(ref l, dir);
+ }
+
+ private void RenderDirectoryList(SerializedObject obj, string propertyName, string humanName)
+ {
+ if (directories == null)
+ {
+ directories = new System.Collections.Generic.List<string>();
+ directories.Add("No Web Content Directory");
+
+ AddSubDirectories(ref directories, Application.dataPath + Path.DirectorySeparatorChar);
+ }
+
+ SerializedProperty target = serializedObject.FindProperty(propertyName);
+
+ int selectedIdx = target.stringValue == null ? 0 : directories.IndexOf(target.stringValue);
+ if (selectedIdx < 0 || selectedIdx >= directories.Count)
+ selectedIdx = 0;
+
+ selectedIdx = EditorGUILayout.Popup(humanName, selectedIdx, directories.ToArray());
+ if (selectedIdx > 0 && selectedIdx < directories.Count)
+ target.stringValue = directories[selectedIdx];
+ else
+ target.stringValue = null;
+ }
+
+ private void AddSubDirectoryFiles(ref System.Collections.Generic.List<string> l, string root)
+ {
+ if (!Directory.Exists(root))
+ return;
+
+ string[] files = Directory.GetFiles(root);
+ foreach (string file in files.Where(f => f.ToLower().EndsWith(".html") || f.ToLower().EndsWith(".htm")))
+ l.Add(file.Substring(Application.dataPath.Length));
+
+ string[] subdirectories = Directory.GetDirectories(root);
+ foreach (string dir in subdirectories)
+ AddSubDirectoryFiles(ref l, dir);
+ }
+
+ private void RenderWebRootSelector(SerializedObject obj, string propertyName, string humanName)
+ {
+ SerializedProperty webRoot = obj.FindProperty("webRoot");
+ SerializedProperty target = serializedObject.FindProperty(propertyName);
+
+ if (files == null)
+ {
+ files = new System.Collections.Generic.List<string>();
+
+ AddSubDirectoryFiles(ref files, Application.dataPath + webRoot.stringValue);
+ if (files.Count == 0)
+ {
+ EditorGUILayout.HelpBox("No suitable html files found in Web Content path.", MessageType.Error);
+ return;
+ }
+ }
+
+ int selectedIdx = 0;
+
+ try
+ {
+ System.Uri uri = string.IsNullOrEmpty(target.stringValue) ? null : new Uri(target.stringValue);
+
+ selectedIdx = uri == null ? 0 : files.IndexOf(uri.AbsolutePath.Replace('/', System.IO.Path.DirectorySeparatorChar));
+ if (selectedIdx < 0 || selectedIdx >= files.Count)
+ selectedIdx = 0;
+ }
+ catch { }
+
+ selectedIdx = EditorGUILayout.Popup(humanName, selectedIdx, files.ToArray());
+ if (selectedIdx >= 0 && selectedIdx < files.Count)
+ {
+ System.UriBuilder builder = new UriBuilder()
+ {
+ Scheme = "file",
+ Path = files[selectedIdx].Replace(System.IO.Path.DirectorySeparatorChar, '/'),
+ Host = ""
+ };
+ target.stringValue = builder.Uri.ToString();
+ }
+ }
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs.meta
new file mode 100644
index 00000000..06aa8999
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_WebPanelEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d09b36020f697be4d9a0f5a6a48cfa83
+timeCreated: 1457992191
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs
new file mode 100644
index 00000000..0193737a
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs
@@ -0,0 +1,20 @@
+#if UNITY_EDITOR && VRC_SDK_VRCSDK2
+using UnityEngine;
+using UnityEditor;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.IO;
+
+namespace VRCSDK2
+{
+ [CustomEditor(typeof(VRC_YouTubeSync))]
+ public class VRC_YouTubeSyncEditor : UnityEditor.Editor
+ {
+ public override void OnInspectorGUI()
+ {
+ EditorGUILayout.HelpBox("This component is deprecated, please use the VRC_SyncVideoPlayer component instead.", MessageType.Error);
+ }
+ }
+}
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs.meta b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs.meta
new file mode 100644
index 00000000..29cadd5d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/VRCSDK/Dependencies/VRChat/Editor/Components/VRC_YouTubeSyncEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 764e26c1ca28e2e45a30c778c1955a47
+timeCreated: 1474675311
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: