├── .gitignore ├── CHANGELOG.md ├── Editor ├── AbstractWindow.cs ├── Actions.cs ├── Broadcasts.cs ├── ExtraWindow.cs ├── FilterWindow.cs ├── StatsWindow.cs ├── TriggerLogger.cs ├── Triggers.cs └── TriggersWindow.cs ├── LICENSE.md ├── README.md ├── TERMS.md └── version.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.meta 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be doocumented in this file. 4 | 5 | ## [2.0.1] 2019-06-25 6 | ### Fixed 7 | - Empty column indicating better what is empty. 8 | - Row color transfering over to the next row when it's hidden. 9 | - Show Empty toggle fixed to actually hide empty... 10 | - Typo in CHANGELOG.md 11 | 12 | Need to stop writing these when I'm exhausted. 13 | 14 | ## [2.0.0] 2019-06-25 15 | ### Added 16 | - Filter SendRPC 17 | - Show Errors/Warnings 18 | - Hide Non Error/Warning 19 | 20 | ### Changed 21 | - New layout for Stats 22 | - New layout for the object viewer 23 | - Moved Terms into TERMS.md 24 | 25 | ### Removed 26 | - Export -------------------------------------------------------------------------------- /Editor/AbstractWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | using UnityEditor; 7 | using VRCSDK2; 8 | 9 | /** 10 | * Author: Christian "PhaxeNor" Wiig 11 | * Website: https://github.com/PhaxeNor/Trigger-Logger 12 | */ 13 | namespace VRCPrefabs.TriggerLogger 14 | { 15 | public abstract class AbstractWindow 16 | { 17 | public static void DrawUILine(Color color, int width = 6, int thickness = 1, int padding = 1) 18 | { 19 | Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness)); 20 | r.height = thickness; 21 | r.y += padding / 2; 22 | r.x -= 1; 23 | r.width += width; 24 | EditorGUI.DrawRect(r, color); 25 | } 26 | 27 | static GUIStyle centeredStyle; 28 | 29 | public static void UILabel(string text) 30 | { 31 | centeredStyle = GUI.skin.GetStyle("Label"); 32 | centeredStyle.alignment = TextAnchor.UpperLeft; 33 | centeredStyle.fontStyle = FontStyle.Bold; 34 | 35 | GUILayout.Label(text); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Editor/Actions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | using UnityEditor; 7 | using VRCSDK2; 8 | 9 | /** 10 | * Author: Christian "PhaxeNor" Wiig 11 | * Website: https://github.com/PhaxeNor/Trigger-Logger 12 | */ 13 | namespace VRCPrefabs.TriggerLogger 14 | { 15 | public class ActionItem 16 | { 17 | public VRC_EventHandler.VrcEventType Type { get; set; } 18 | public int Total { get; set; } 19 | 20 | public string GetTypeName() { return Type.ToString(); } 21 | } 22 | 23 | public class ActionList 24 | { 25 | public List list { get; private set; } 26 | 27 | public void generateList() 28 | { 29 | list = new List(); 30 | 31 | foreach(VRC_EventHandler.VrcEventType action in Enum.GetValues(typeof(VRC_EventHandler.VrcEventType))) 32 | { 33 | list.Add(new ActionItem() { Type = action, Total = 0 }); 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Editor/Broadcasts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | using UnityEditor; 7 | using VRCSDK2; 8 | 9 | /** 10 | * Author: Christian "PhaxeNor" Wiig 11 | * Website: https://github.com/PhaxeNor/Trigger-Logger 12 | */ 13 | namespace VRCPrefabs.TriggerLogger 14 | { 15 | public class BroadcastItem 16 | { 17 | public VRC_EventHandler.VrcBroadcastType Type { get; set; } 18 | public int Total { get; set; } 19 | public int RPC { get; set; } 20 | 21 | public string GetTypeName() { return Type.ToString(); } 22 | } 23 | 24 | public class BroadcastList 25 | { 26 | public List list { get; private set; } 27 | 28 | public void generateList() 29 | { 30 | list = new List(); 31 | 32 | foreach(VRC_EventHandler.VrcBroadcastType broadcast in Enum.GetValues(typeof(VRC_EventHandler.VrcBroadcastType))) 33 | { 34 | list.Add(new BroadcastItem() { Type = broadcast, Total = 0, RPC = 0 }); 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Editor/ExtraWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | using UnityEditor; 7 | using VRCSDK2; 8 | 9 | /** 10 | * Author: Christian "PhaxeNor" Wiig 11 | * Website: https://github.com/PhaxeNor/Trigger-Logger 12 | */ 13 | namespace VRCPrefabs.TriggerLogger 14 | { 15 | public class ExtraWindow : AbstractWindow 16 | { 17 | public void drawWindow(TriggerLogger triggerLogger) 18 | { 19 | var guicolor = GUI.backgroundColor; 20 | 21 | UILabel("Help"); 22 | 23 | GUI.backgroundColor = Color.gray; 24 | GUILayout.BeginHorizontal("helpbox"); 25 | GUILayout.Label("Disabled"); 26 | GUILayout.EndHorizontal(); 27 | 28 | GUI.backgroundColor = Color.yellow; 29 | GUILayout.BeginHorizontal("helpbox"); 30 | GUILayout.Label("Warning"); 31 | GUILayout.EndHorizontal(); 32 | 33 | GUI.backgroundColor = Color.red; 34 | GUILayout.BeginHorizontal("helpbox"); 35 | GUILayout.Label("Error"); 36 | GUILayout.EndHorizontal(); 37 | 38 | GUI.backgroundColor = Color.cyan; 39 | GUILayout.BeginHorizontal("helpbox"); 40 | GUILayout.Label("Prefab"); 41 | GUILayout.EndHorizontal(); 42 | 43 | 44 | GUI.backgroundColor = guicolor; 45 | 46 | GUILayout.Space(10); 47 | 48 | UILabel("Author: PhaxeNor"); 49 | 50 | GUILayout.BeginHorizontal(); 51 | 52 | if (GUILayout.Button("Twitter")) 53 | { 54 | Application.OpenURL("https://twitter.com/phaxenor"); 55 | } 56 | 57 | if (GUILayout.Button("Github")) 58 | { 59 | Application.OpenURL("https://github.com/PhaxeNor/Trigger-Logger"); 60 | } 61 | 62 | GUILayout.EndHorizontal(); 63 | 64 | 65 | 66 | GUILayout.Space(10); 67 | 68 | UILabel("VRC Prefabs"); 69 | 70 | if (GUILayout.Button("Twitter")) 71 | { 72 | Application.OpenURL("https://twitter.com/VRCPrefabs"); 73 | } 74 | 75 | if (GUILayout.Button("Github")) 76 | { 77 | Application.OpenURL("https://github.com/vrc-prefabs"); 78 | } 79 | 80 | if (GUILayout.Button("Website")) 81 | { 82 | Application.OpenURL("https://vrcprefabs.com"); 83 | } 84 | 85 | if (GUILayout.Button("Unofficial Wiki")) 86 | { 87 | Application.OpenURL("https://vrchat.wikidot.com"); 88 | } 89 | 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /Editor/FilterWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Linq; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEngine; 7 | using UnityEditor; 8 | using VRCSDK2; 9 | 10 | /** 11 | * Author: Christian "PhaxeNor" Wiig 12 | * Website: https://github.com/PhaxeNor/Trigger-Logger 13 | */ 14 | 15 | namespace VRCPrefabs.TriggerLogger 16 | { 17 | public class FilterWindow : AbstractWindow 18 | { 19 | public void drawWindow(TriggerLogger tl) 20 | { 21 | GUILayout.Space(5); 22 | 23 | tl.query = EditorGUILayout.TextField("GameObject Search", tl.query); 24 | 25 | GUILayout.Space(5); 26 | 27 | UILabel("VRC Trigger"); 28 | 29 | var oldTFalgs = tl.triggerFlags; 30 | 31 | tl.triggerFlags = EditorGUILayout.MaskField("Triggers", tl.triggerFlags, tl.triggerTypes.ToArray()); 32 | 33 | if(tl.triggerFlags != oldTFalgs) 34 | { 35 | tl.triggerFilter.Clear(); 36 | for (int i = 0; i < tl.triggerTypes.ToArray().Length; i++) 37 | { 38 | if ((tl.triggerFlags & (1 << i)) == (1 << i)) tl.triggerFilter.Add(tl.triggerTypes.ToArray()[i]); 39 | } 40 | } 41 | 42 | var oldBFalgs = tl.broadcastFlags; 43 | 44 | tl.broadcastFlags = EditorGUILayout.MaskField("Broadcasts", tl.broadcastFlags, tl.broadcasTypes.ToArray()); 45 | 46 | if (tl.broadcastFlags != oldBFalgs) 47 | { 48 | tl.broadcastFilter.Clear(); 49 | for (int i = 0; i < tl.broadcasTypes.ToArray().Length; i++) 50 | { 51 | if ((tl.broadcastFlags & (1 << i)) == (1 << i)) tl.broadcastFilter.Add(tl.broadcasTypes.ToArray()[i]); 52 | } 53 | } 54 | 55 | var oldAFalgs = tl.actionsFlags; 56 | 57 | tl.actionsFlags = EditorGUILayout.MaskField("Actions", tl.actionsFlags, tl.actionsTypes.ToArray()); 58 | 59 | if (tl.actionsFlags != oldAFalgs) 60 | { 61 | tl.actionFilter.Clear(); 62 | for (int i = 0; i < tl.actionsTypes.ToArray().Length; i++) 63 | { 64 | if ((tl.actionsFlags & (1 << i)) == (1 << i)) tl.actionFilter.Add(tl.actionsTypes.ToArray()[i]); 65 | } 66 | } 67 | 68 | GUILayout.Space(5); 69 | 70 | if(tl.sendRpcMethods.Count > 0) 71 | { 72 | var oldRPCFalgs = tl.RpcMethodsFlags; 73 | 74 | tl.RpcMethodsFlags = EditorGUILayout.MaskField("SendRPC Methods", tl.RpcMethodsFlags, tl.sendRpcMethods.ToArray()); 75 | 76 | if (tl.RpcMethodsFlags != oldRPCFalgs) 77 | { 78 | tl.RpcMethodsFilter.Clear(); 79 | for (int i = 0; i < tl.sendRpcMethods.ToArray().Length; i++) 80 | { 81 | if ((tl.RpcMethodsFlags & (1 << i)) == (1 << i)) tl.RpcMethodsFilter.Add(tl.sendRpcMethods.ToArray()[i]); 82 | } 83 | } 84 | 85 | GUILayout.Space(5); 86 | } 87 | 88 | UILabel("Advanced"); 89 | 90 | tl.ShowPrefabs = EditorGUILayout.Toggle("Show Prefabs", tl.ShowPrefabs); 91 | 92 | tl.ShowEmpty = EditorGUILayout.Toggle("Show Empty", tl.ShowEmpty); 93 | 94 | tl.ShowErrors = EditorGUILayout.Toggle("Show Errors/Warnings", tl.ShowErrors); 95 | 96 | GUILayout.Space(5); 97 | 98 | tl.HideNonErrors = EditorGUILayout.Toggle("Hide Non Error/Warning", tl.HideNonErrors); 99 | 100 | GUILayout.Space(10); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /Editor/StatsWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | using UnityEditor; 7 | using VRCSDK2; 8 | 9 | /** 10 | * Author: Christian "PhaxeNor" Wiig 11 | * Website: https://github.com/PhaxeNor/Trigger-Logger 12 | */ 13 | namespace VRCPrefabs.TriggerLogger 14 | { 15 | public class StatsWindow : AbstractWindow 16 | { 17 | private enum StatsType 18 | { 19 | Broadcasts, 20 | Triggers, 21 | Actions 22 | } 23 | 24 | StatsType dropdown = StatsType.Broadcasts; 25 | 26 | Vector2 scrollLocation; 27 | 28 | public void drawWindow(TriggerLogger triggerLogger) 29 | { 30 | GUILayout.Space(5); 31 | 32 | dropdown = (StatsType)EditorGUILayout.EnumPopup(dropdown); 33 | 34 | triggerLogger.StatsShowZero = GUILayout.Toggle(triggerLogger.StatsShowZero, "Show with zero"); 35 | 36 | scrollLocation = EditorGUILayout.BeginScrollView(scrollLocation); 37 | 38 | switch (dropdown) 39 | { 40 | case StatsType.Broadcasts: ShowBroadcasts(triggerLogger); break; 41 | case StatsType.Triggers: ShowTriggers(triggerLogger); break; 42 | case StatsType.Actions: ShowActions(triggerLogger); break; 43 | } 44 | 45 | EditorGUILayout.EndScrollView(); 46 | } 47 | 48 | private void ShowBroadcasts(TriggerLogger triggerLogger) 49 | { 50 | var win = Screen.width * 0.8; 51 | var w1 = win * 0.17; var w2 = win * 0.06; 52 | 53 | var centeredStyle = new GUIStyle(GUI.skin.label); 54 | centeredStyle.alignment = TextAnchor.UpperCenter; 55 | 56 | GUILayout.Label("Broadcasts: " + triggerLogger.broadcasts.list.Where(t => t.Type != VRC_EventHandler.VrcBroadcastType.Local).Sum(t => t.Total).ToString() + " - Non-local"); 57 | GUILayout.Label("Network: " + triggerLogger.broadcasts.list.Sum(t => t.RPC).ToString()); 58 | 59 | GUILayout.Space(5); 60 | 61 | EditorGUILayout.BeginHorizontal(); 62 | GUILayout.Label("Type", GUILayout.Width((float)w1)); 63 | GUILayout.Label("Total", centeredStyle, GUILayout.Width((float)w2)); 64 | GUILayout.Label("RPC", centeredStyle, GUILayout.Width((float)w2)); 65 | EditorGUILayout.EndHorizontal(); 66 | 67 | triggerLogger.broadcasts.list.ForEach(bl => 68 | { 69 | if (!triggerLogger.StatsShowZero && bl.Total == 0) return; 70 | 71 | DrawUILine(Color.gray); 72 | EditorGUILayout.BeginHorizontal(); 73 | EditorGUILayout.LabelField(bl.Type.ToString(), GUILayout.Width((float)w1)); 74 | EditorGUILayout.LabelField(bl.Total.ToString(), centeredStyle, GUILayout.Width((float)w2)); 75 | EditorGUILayout.LabelField(bl.RPC.ToString(), centeredStyle, GUILayout.Width((float)w2)); 76 | EditorGUILayout.EndHorizontal(); 77 | }); 78 | 79 | 80 | } 81 | 82 | private void ShowTriggers(TriggerLogger triggerLogger) 83 | { 84 | var win = Screen.width * 0.8; 85 | var w1 = win * 0.20; var w2 = win * 0.06; 86 | 87 | var centeredStyle = new GUIStyle(GUI.skin.label); 88 | centeredStyle.alignment = TextAnchor.UpperCenter; 89 | 90 | GUILayout.Label("Triggers: " + triggerLogger.triggers.list.Sum(t => t.Total).ToString()); 91 | GUILayout.Space(5); 92 | 93 | EditorGUILayout.BeginHorizontal(); 94 | GUILayout.Label("Type", GUILayout.Width((float)w1)); 95 | GUILayout.Label("Total", centeredStyle, GUILayout.Width((float)w2)); 96 | EditorGUILayout.EndHorizontal(); 97 | 98 | triggerLogger.triggers.list.ForEach(bl => 99 | { 100 | if (!triggerLogger.StatsShowZero && bl.Total == 0) return; 101 | 102 | DrawUILine(Color.gray); 103 | EditorGUILayout.BeginHorizontal(); 104 | EditorGUILayout.LabelField(bl.Type.ToString(), GUILayout.Width((float)w1)); 105 | EditorGUILayout.LabelField(bl.Total.ToString(), centeredStyle, GUILayout.Width((float)w2)); 106 | EditorGUILayout.EndHorizontal(); 107 | }); 108 | } 109 | 110 | private void ShowActions(TriggerLogger triggerLogger) 111 | { 112 | var win = Screen.width * 0.8; 113 | var w1 = win * 0.20; var w2 = win * 0.06; 114 | 115 | var centeredStyle = new GUIStyle(GUI.skin.label); 116 | centeredStyle.alignment = TextAnchor.UpperCenter; 117 | 118 | GUILayout.Label("Actions: " + triggerLogger.actions.list.Sum(t => t.Total).ToString()); 119 | GUILayout.Space(5); 120 | 121 | EditorGUILayout.BeginHorizontal(); 122 | GUILayout.Label("Type", GUILayout.Width((float)w1)); 123 | GUILayout.Label("Total", centeredStyle, GUILayout.Width((float)w2)); 124 | EditorGUILayout.EndHorizontal(); 125 | 126 | triggerLogger.actions.list.ForEach(bl => 127 | { 128 | if (!triggerLogger.StatsShowZero && bl.Total == 0) return; 129 | 130 | DrawUILine(Color.gray); 131 | EditorGUILayout.BeginHorizontal(); 132 | EditorGUILayout.LabelField(bl.Type.ToString(), GUILayout.Width((float)w1)); 133 | EditorGUILayout.LabelField(bl.Total.ToString(), centeredStyle, GUILayout.Width((float)w2)); 134 | EditorGUILayout.EndHorizontal(); 135 | }); 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /Editor/TriggerLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | using UnityEditor; 7 | using VRCSDK2; 8 | using UnityEngine.Networking; 9 | 10 | /** 11 | * Author: Christian "PhaxeNor" Wiig 12 | * Website: https://github.com/PhaxeNor/Trigger-Logger 13 | */ 14 | namespace VRCPrefabs.TriggerLogger 15 | { 16 | public class TriggerLogger : EditorWindow 17 | { 18 | public List triggerList = new List(); 19 | public TriggerList triggers = new TriggerList(); 20 | public List triggerTypes = new List(); 21 | 22 | public List dynamicPrefabs = new List(); 23 | 24 | public BroadcastList broadcasts = new BroadcastList(); 25 | public List broadcasTypes = new List(); 26 | 27 | public ActionList actions = new ActionList(); 28 | public List actionsTypes = new List(); 29 | 30 | public List sendRpcMethods = new List(); 31 | public List RpcMethodsFilter = new List(); 32 | public int RpcMethodsFlags = -1; 33 | 34 | [MenuItem("VRC Prefabs/Trigger Logger")] 35 | public static void ShowMenu() 36 | { 37 | EditorWindow window = GetWindow("Trigger Logger"); 38 | window.maxSize = new Vector2(2000, 9999); 39 | window.minSize = new Vector2(1000, 320); 40 | window.Show(); 41 | } 42 | 43 | FilterWindow filterWindow = new FilterWindow(); 44 | StatsWindow statsWindow = new StatsWindow(); 45 | ExtraWindow extraWindow = new ExtraWindow(); 46 | TriggersWindow triggersWindow = new TriggersWindow(); 47 | 48 | public List triggerFilter = new List(); 49 | public List broadcastFilter = new List(); 50 | public List actionFilter = new List(); 51 | 52 | // Settings 53 | public bool ShowPrefabs = false; 54 | public bool ShowEmpty = true; 55 | public bool ShowErrors = true; 56 | public bool StatsShowZero = true; 57 | public bool HideNonErrors = false; 58 | public string query = ""; 59 | public string SendRPCquery = ""; 60 | 61 | public int triggerFlags = -1; 62 | public int broadcastFlags = -1; 63 | public int actionsFlags = -1; 64 | public int rpcFlags = -1; 65 | 66 | void OnEnable() 67 | { 68 | triggerTypes = Enum.GetNames(typeof(VRC_Trigger.TriggerType)).Select(x => x.ToString()).ToList(); 69 | broadcasTypes = Enum.GetNames(typeof(VRC_EventHandler.VrcBroadcastType)).Select(x => x.ToString()).ToList(); 70 | actionsTypes = Enum.GetNames(typeof(VRC_EventHandler.VrcEventType)).Select(x => x.ToString()).ToList(); 71 | 72 | BuildLogger(); 73 | } 74 | 75 | void OnFocus() 76 | { 77 | if (EditorPrefs.HasKey("TriggerLogger.ShowPrefabs")) ShowPrefabs = EditorPrefs.GetBool("TriggerLogger.ShowPrefabs"); 78 | if (EditorPrefs.HasKey("TriggerLogger.ShowEmpty")) ShowEmpty = EditorPrefs.GetBool("TriggerLogger.ShowEmpty"); 79 | if (EditorPrefs.HasKey("TriggerLogger.StatsShowZero")) StatsShowZero = EditorPrefs.GetBool("TriggerLogger.StatsShowZero"); 80 | 81 | BuildLogger(); 82 | } 83 | 84 | void OnLostFocus() 85 | { 86 | savePrefs(); 87 | } 88 | 89 | void OnDestroy() 90 | { 91 | savePrefs(); 92 | } 93 | 94 | void savePrefs() 95 | { 96 | EditorPrefs.SetBool("TriggerLogger.ShowPrefabs", ShowPrefabs); 97 | EditorPrefs.SetBool("TriggerLogger.ShowEmpty", ShowEmpty); 98 | EditorPrefs.SetBool("TriggerLogger.StatsShowZero", StatsShowZero); 99 | } 100 | 101 | int tab = 0; 102 | 103 | void OnGUI() 104 | { 105 | GUILayout.BeginArea(new Rect(0, 0, 300, position.height), new GUIStyle(GUI.skin.box)); 106 | 107 | tab = GUILayout.Toolbar(tab, new string[] { "Triggers", "Stats", "Extra" }); 108 | 109 | switch(tab) 110 | { 111 | case 0: filterWindow.drawWindow(this); break; 112 | case 1: statsWindow.drawWindow(this); break; 113 | case 2: extraWindow.drawWindow(this); break; 114 | } 115 | 116 | GUILayout.EndArea(); 117 | 118 | GUILayout.BeginArea(new Rect(300, 0, position.width - 300, position.height)); 119 | 120 | triggersWindow.drawWindow(this); 121 | 122 | GUILayout.EndArea(); 123 | } 124 | 125 | void OnSelectionChange() 126 | { 127 | this.Repaint(); 128 | } 129 | 130 | void BuildLogger() 131 | { 132 | triggers.generateList(); 133 | broadcasts.generateList(); 134 | actions.generateList(); 135 | 136 | triggerList.Clear(); 137 | triggerList.AddRange(Resources.FindObjectsOfTypeAll()); 138 | 139 | triggerList.ForEach(t => 140 | { 141 | if (t.gameObject.scene.name == null) return; 142 | 143 | t.Triggers.ForEach(tr => 144 | { 145 | broadcasts.list.Where(l => l.Type == tr.BroadcastType).Select(b => 146 | { 147 | b.Total += 1; 148 | if (tr.BroadcastType != VRC_EventHandler.VrcBroadcastType.Local) 149 | { 150 | b.RPC += tr.Events.Sum(e => e.ParameterObjects.Count()); 151 | } 152 | 153 | return b; 154 | }).ToList(); 155 | 156 | triggers.list.Where(tl => tl.Type == tr.TriggerType).Select(l => 157 | { 158 | return l.Total += 1; 159 | }).ToList(); 160 | 161 | tr.Events.ForEach(e => 162 | { 163 | actions.list.Where(a => a.Type == e.EventType).Select(s => { return s.Total += 1; }).ToList(); 164 | 165 | if (e.EventType == VRC_EventHandler.VrcEventType.SendRPC) 166 | { 167 | sendRpcMethods.Add(e.ParameterString); 168 | } 169 | }); 170 | }); 171 | }); 172 | 173 | triggerList.Reverse(); 174 | } 175 | 176 | static string GetCurrentVersion() 177 | { 178 | string currentVersion = ""; 179 | string versionTextPath = Application.dataPath + "/VRCPrefabs/Scripts/TriggerLogger/VERSION.md"; 180 | if (System.IO.File.Exists(versionTextPath)) 181 | { 182 | string[] versionFileLines = System.IO.File.ReadAllLines(versionTextPath); 183 | if (versionFileLines.Length > 0) 184 | currentVersion = versionFileLines[0]; 185 | } 186 | return currentVersion; 187 | } 188 | } 189 | } -------------------------------------------------------------------------------- /Editor/Triggers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using VRCSDK2; 4 | 5 | /** 6 | * Author: Christian "PhaxeNor" Wiig 7 | * Website: https://github.com/PhaxeNor/Trigger-Logger 8 | */ 9 | namespace VRCPrefabs.TriggerLogger 10 | { 11 | public class TriggerItem 12 | { 13 | public VRC_Trigger Trigger { get; set; } 14 | } 15 | 16 | public class Trigger 17 | { 18 | public VRC_Trigger.TriggerType Type { get; set; } 19 | public int Total { get; set; } 20 | } 21 | 22 | public class TriggerList 23 | { 24 | public List list { get; private set; } 25 | 26 | public void generateList() 27 | { 28 | list = new List(); 29 | 30 | foreach(VRC_Trigger.TriggerType type in Enum.GetValues(typeof(VRC_Trigger.TriggerType))) 31 | { 32 | list.Add(new Trigger() 33 | { 34 | Type = type, 35 | Total = 0 36 | }); 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /Editor/TriggersWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using UnityEngine; 6 | using UnityEditor; 7 | using VRCSDK2; 8 | 9 | /** 10 | * Author: Christian "PhaxeNor" Wiig 11 | * Website: https://github.com/PhaxeNor/Trigger-Logger 12 | */ 13 | namespace VRCPrefabs.TriggerLogger 14 | { 15 | public class TriggersWindow : AbstractWindow 16 | { 17 | Vector2 scrollLocation; 18 | 19 | public void drawWindow(TriggerLogger tl) 20 | { 21 | GUILayout.Space(5); 22 | 23 | var win = Screen.width * 0.8; 24 | var w1 = win * 0.35; var w2 = win * 0.10; var w3 = win * 0.10; var w4 = win * 0.10; 25 | 26 | var centeredStyle = new GUIStyle(GUI.skin.label); 27 | centeredStyle.alignment = TextAnchor.UpperCenter; 28 | 29 | GUILayout.BeginHorizontal("helpbox"); 30 | 31 | GUILayout.Label("GameObject", GUILayout.Width((float)w1)); 32 | 33 | GUILayout.Label("Triggers", centeredStyle, GUILayout.Width((float)w2)); 34 | 35 | GUILayout.Label("Actions", centeredStyle, GUILayout.Width((float)w2)); 36 | 37 | GUILayout.Label("Broadcasts", centeredStyle, GUILayout.Width((float)w2)); 38 | 39 | GUILayout.Label("Empty", centeredStyle, GUILayout.Width((float)w2)); 40 | 41 | 42 | GUILayout.EndHorizontal(); 43 | 44 | scrollLocation = EditorGUILayout.BeginScrollView(scrollLocation); 45 | 46 | if (tl.triggerList.Count > 0) 47 | { 48 | var guiColor = GUI.backgroundColor; 49 | 50 | for (var i = 0; i < tl.triggerList.Count; i++) 51 | { 52 | var trigger = tl.triggerList[i]; 53 | 54 | List errors = new List(); 55 | 56 | if (trigger == null) continue; 57 | 58 | if (!tl.ShowPrefabs && trigger.gameObject.scene.name == null) continue; 59 | 60 | if (tl.query != "" && !trigger.gameObject.name.ToLower().Contains(tl.query.ToLower())) continue; 61 | 62 | var empty = trigger.Triggers.Sum(t => t.Events.Count(e => e.ParameterObjects.Count() > 0)); 63 | 64 | if (tl.SendRPCquery != "" && !trigger.Triggers.Exists(t => { return t.Events.Exists(e => e.ParameterString.ToLower().Contains(tl.SendRPCquery.ToLower())); })) continue; 65 | 66 | if (!tl.ShowEmpty && empty == 0) continue; 67 | 68 | if (tl.triggerFlags == 0 || tl.broadcastFlags == 0 || tl.actionsFlags == 0) continue; 69 | 70 | if (tl.triggerFlags != 0 || tl.broadcastFlags != 0 || tl.actionsFlags != 0) 71 | { 72 | if (tl.triggerFlags != 0 && tl.triggerFlags != -1 && !trigger.Triggers.Exists(t => { return tl.triggerFilter.Exists(o => t.TriggerType.ToString() == o); })) continue; 73 | if (tl.broadcastFlags != 0 && tl.broadcastFlags != -1 && !trigger.Triggers.Exists(t => { return tl.broadcastFilter.Exists(o => t.BroadcastType.ToString() == o); })) continue; 74 | if (tl.actionsFlags != 0 && tl.actionsFlags != -1 && !trigger.Triggers.Exists(t => { return t.Events.Exists(e => tl.actionFilter.Exists(o => e.EventType.ToString() == o)); })) continue; 75 | 76 | if (tl.RpcMethodsFlags != 0 && tl.RpcMethodsFlags != -1 && !trigger.Triggers.Exists(t => { return t.Events.Exists(e => tl.RpcMethodsFilter.Exists(o => e.ParameterString.ToString() == o)); })) continue; 77 | } 78 | 79 | var triggers = trigger.Triggers.Count(); 80 | var events = trigger.Triggers.Sum(t => t.Events.Count); 81 | var broadcasts = trigger.Triggers.Where(t => t.BroadcastType != VRC_EventHandler.VrcBroadcastType.Local).Count(); 82 | 83 | 84 | 85 | if (i % 2 == 1) GUI.backgroundColor = new Color(0.80f, 0.80f, 0.80f, 1f); 86 | 87 | if (triggers == 0) 88 | { 89 | errors.Add("Object has the VRC_Trigger componet, but no triggers"); 90 | GUI.backgroundColor = Color.red; 91 | } 92 | if (!trigger.gameObject.activeInHierarchy || !trigger.isActiveAndEnabled) 93 | { 94 | if (trigger.gameObject.scene.name != null) errors.Add("Trigger is disabled"); 95 | GUI.backgroundColor = Color.yellow; 96 | } 97 | 98 | if (missingTeleportTo(trigger)) 99 | { 100 | errors.Add("TeleportTo target is empty"); 101 | GUI.backgroundColor = Color.yellow; 102 | } 103 | 104 | if (empty == 0) 105 | { 106 | errors.Add("Trigger doesn't have any actions."); 107 | GUI.backgroundColor = Color.red; 108 | } 109 | if (trigger.gameObject.scene.name == null) GUI.backgroundColor = Color.cyan; 110 | 111 | if (Selection.objects.Contains(trigger.gameObject)) 112 | { 113 | GUI.backgroundColor = new Color(0.047f, 0.564f, 0.929f, 1); 114 | } 115 | 116 | if (errors.Count > 0 && !tl.ShowErrors) { 117 | GUI.backgroundColor = guiColor; 118 | continue; 119 | } 120 | if (errors.Count == 0 && tl.HideNonErrors) { 121 | GUI.backgroundColor = guiColor; 122 | continue; 123 | } 124 | 125 | GUILayout.BeginVertical("helpbox"); 126 | 127 | GUILayout.BeginHorizontal(); 128 | 129 | EditorGUILayout.ObjectField(trigger.gameObject, typeof(GameObject), true, GUILayout.Width((float)w1)); 130 | 131 | GUILayout.Label(triggers.ToString(), centeredStyle, GUILayout.Width((float)w2)); 132 | 133 | GUILayout.Label(events.ToString(), centeredStyle, GUILayout.Width((float)w2)); 134 | 135 | GUILayout.Label(broadcasts.ToString(), centeredStyle, GUILayout.Width((float)w2)); 136 | 137 | GUILayout.Label((empty > 0) ? "No" : "Yes", centeredStyle, GUILayout.Width((float)w2)); 138 | 139 | GUILayout.EndHorizontal(); 140 | 141 | if (errors.Count > 0) 142 | { 143 | GUILayout.BeginVertical(); 144 | 145 | errors.ForEach(e => 146 | { 147 | GUILayout.Label(e); 148 | }); 149 | 150 | GUILayout.EndVertical(); 151 | } 152 | 153 | GUILayout.EndVertical(); 154 | 155 | if (Event.current.type == EventType.MouseDown && GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) 156 | { 157 | GameObject[] selected = new GameObject[1]; 158 | selected[0] = trigger.gameObject; 159 | 160 | Selection.objects = selected; 161 | 162 | tl.Repaint(); 163 | } 164 | 165 | GUI.backgroundColor = guiColor; 166 | } 167 | } 168 | 169 | EditorGUILayout.EndScrollView(); 170 | } 171 | 172 | bool missingTeleportTo(VRC_Trigger trigger) 173 | { 174 | var emptyTeleport = false; 175 | 176 | trigger.Triggers 177 | .ForEach(t => { 178 | t.Events.ForEach(e => 179 | { 180 | if(e.EventType == VRC_EventHandler.VrcEventType.SendRPC && e.ParameterString == "TeleportTo") 181 | { 182 | object[] param = VRC_Serialization.ParameterDecoder(e.ParameterBytes); 183 | 184 | if(param.Length < 1 || param[0] == null) 185 | { 186 | emptyTeleport = true; 187 | } 188 | } 189 | }); 190 | }); 191 | 192 | return emptyTeleport; 193 | } 194 | 195 | } 196 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 PhaxeNor 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Trigger Logger 2 | [![Github All Releases](https://img.shields.io/github/downloads/PhaxeNor/Trigger-Logger/total.svg?style=for-the-badge)](https://github.com/PhaxeNor/Trigger-Logger/releases) [![Twitter Follow](https://img.shields.io/twitter/follow/phaxenor.svg?style=for-the-badge&label=Twitter)](https://twitter.com/PhaxeNor) 3 | 4 | Trigger Logger is a Unity Editor script that will give you a list of all your VRC_Triggers. 5 | It will give you information about each game object that has a VRC_Trigger on it. 6 | 7 | This was created so that you could get a better overview over your triggers. 8 | 9 | ### Current Features 10 | - List over triggers 11 | - Stats (Total triggers, broadcasts and actions) 12 | - Filtering (Triggers, broadcast, actions and SendRPC) 13 | - Toggle what you want to see (Prefabs, empty triggers, errors/warnings) 14 | 15 | Support and help is done via Discord, Twitter or Github. 16 | 17 | Discord Tag: PhaxeNor#0001 18 | 19 | 20 | ### Notes 21 | A bug in the filtering that I haven't been able to figure out yet is when you select the first type the last one will also be selected. 22 | This isn't something that will prevent it from working, you just got to be aware of it. 23 | -------------------------------------------------------------------------------- /TERMS.md: -------------------------------------------------------------------------------- 1 | Trigger Logger 2 | 3 | This tool was created with the intention that you could get 4 | a better overview over your triggers. It is by no means perfect 5 | and could contain flaws. 6 | 7 | Terms & Conditions 8 | 9 | By using this tool you also accept that I, the creator, is not to be held liable for any damages that may occur by using this tool. 10 | All actions except filling the list with triggers is done on the users own accord. 11 | Filling the list is done using STANDARD Unity code. -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 2.0.1 --------------------------------------------------------------------------------