Exemple #1
0
        public override void OnInspectorGUI()
        {
            droppedObjects = false;
            isPlaying      = !Application.isPlaying;
            t = (UdonSharpBehaviour)target;
            if (cT == null)
            {
                cT         = t.GetType();
                undoString = $"Update {cT.Name}";
            }

            if (drawDefaultInspector)
            {
                DrawDefaultGUI(t);
                return;
            }
            if (UdonSharpGUI.DrawDefaultUdonSharpBehaviourHeader(t, true))
            {
                return;
            }
            // Header
            var customNameAttr = cT.GetCustomAttributes(typeof(CustomNameAttribute))
                                 .Select(i => i as CustomNameAttribute).ToArray();
            var helpUrlAttribute = cT.GetCustomAttributes(typeof(HelpURLAttribute))
                                   .Select(i => i as HelpURLAttribute).ToArray();

            if (customNameAttr.Any() || helpUrlAttribute.Any())
            {
                EditorGUILayout.BeginHorizontal();
                UTStyles.RenderHeader(customNameAttr.Any() ? customNameAttr[0].name : cT.Name.Replace("Controller", ""));
                if (helpUrlAttribute.Any())
                {
                    if (GUILayout.Button("?", GUILayout.Height(26), GUILayout.Width(26)))
                    {
                        Application.OpenURL(helpUrlAttribute[0].URL);
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            EditorGUI.BeginChangeCheck();
            serializedObject.Update();

            // Help Box
            var helpBoxAttr = cT.GetCustomAttributes(typeof(HelpMessageAttribute))
                              .Select(i => i as HelpMessageAttribute).ToArray();

            if (helpBoxAttr.Any())
            {
                UTStyles.RenderNote(helpBoxAttr[0]?.helpMessage);
            }

            // Check prefabs
            if (PrefabUtility.IsPartOfAnyPrefab(t.gameObject))
            {
                EditorGUILayout.HelpBox(
                    "Udon doesn't play well with Prefabs. " +
                    "It is recommended to unpack your prefabs when modifying any values.\n" +
                    "Right click the prefab and choose \"Unpack Prefab\"", MessageType.Warning);
            }

            // Before Editor Callback
            var beforeEditorCallback = cT.GetCustomAttribute <OnBeforeEditorAttribute>();

            if (beforeEditorCallback != null)
            {
                var m = cT.GetMethod(beforeEditorCallback.methodName);
                m?.Invoke(t, new object[] { serializedObject });
            }

            // for direct editing of fields in case of jagged arrays - we need to record changes
            Undo.RecordObject(t, undoString);

            // Actual GUI
            try {
                DrawGUI(t);
            } catch (Exception ex) {
                // for some reason unity likes to throw ExitGUI exceptions when looking up scene objects
                // even tho it doesnt throw them when you don't try-catch
                if (ex.GetType() != typeof(ExitGUIException))
                {
                    Debug.LogException(ex);
                }
            }

            // After Editor Callback
            var afterEditorCallback = cT.GetCustomAttribute <OnAfterEditorAttribute>();

            if (afterEditorCallback != null)
            {
                var m = cT.GetMethod(afterEditorCallback.methodName);
                m?.Invoke(t, new object[] { serializedObject });
            }

            if (EditorGUI.EndChangeCheck() || droppedObjects)
            {
                // Global Values Callback
                var globalEditorCallback = cT.GetCustomAttribute <OnValuesChangedAttribute>();
                if (globalEditorCallback != null)
                {
                    var m = cT.GetMethod(globalEditorCallback.methodName);
                    m?.Invoke(t, new object[] { serializedObject });
                }
                serializedObject.ApplyModifiedProperties();
            }

            if (droppedObjects)
            {
                return;
            }

            // Extra Methods
            var methods = cT.GetMethods(methodFlags).Where(i => i.GetCustomAttribute <ButtonAttribute>() != null).ToArray();
            var buttons = methods
                          .Select(i => i.GetCustomAttribute <ButtonAttribute>())
                          .Where(i => i != null)
                          .ToArray();

            if (buttons.Any())
            {
                UTStyles.RenderSectionHeader("Methods");
                var rowBreak = Mathf.Max(1, Mathf.Min(3, buttons.Length - 1));
                var rowEndI  = -100;
                foreach (var(button, i) in buttons.WithIndex())
                {
                    if (i == rowEndI && i != buttons.Length - 1)
                    {
                        EditorGUILayout.EndHorizontal();
                    }
                    if (i % rowBreak == 0 && i != buttons.Length - 1)
                    {
                        EditorGUILayout.BeginHorizontal();
                        rowEndI = Math.Min(i + rowBreak, buttons.Length - 1);
                    }
                    EditorGUI.BeginDisabledGroup(isPlaying && !button.activeInEditMode);
                    if (GUILayout.Button(button.text))
                    {
                        if (button.activeInEditMode)
                        {
                            methods[i].Invoke(t, new object[] {});
                        }
                        else
                        {
                            UdonSharpEditorUtility.GetProxyBehaviour(t.GetComponent <UdonBehaviour>()).SendCustomEvent(methods[i].Name);
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                    if (i == buttons.Length - 1 && rowEndI != -100)
                    {
                        EditorGUILayout.EndHorizontal();
                    }
                }
            }

            UTStyles.HorizontalLine();
            if (GUILayout.Button("Show Default Inspector", UTStyles.smallButton))
            {
                drawDefaultInspector = true;
            }
        }