예제 #1
0
        private void OnGUI()
        {
            emptyLayer = 0;
            UTUtils.GetLayerMasks();
            UTStyles.RenderHeader("Camera System Setup");
            UTStyles.RenderNote("This tool will set up a camera system in your scene, for more details on how to customize the camera - consult the documentation page.");
            if (GUILayout.Button("Documentation", GUILayout.ExpandWidth(true)))
            {
                Application.OpenURL(WikiURL);
            }

            UTStyles.RenderSectionHeader("Position and Style");

            var newCameraSpot = (Transform)EditorGUILayout.ObjectField("Camera Position", cameraSpot, typeof(Transform), true);

            if (newCameraSpot != cameraSpot)
            {
                setup = false;
            }

            cameraSpot = newCameraSpot;
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Watermark Overlay");
            watermark = (Texture)EditorGUILayout.ObjectField(watermark, typeof(Texture), true);
            EditorGUILayout.EndHorizontal();
            UTStyles.RenderNote("Overlay should be a 16:9 transparent texture");
            addGuide = EditorGUILayout.Toggle("Add Camera Guide", addGuide);
            if (addGuide)
            {
                var newGuideStyle = (GuideStyle)EditorGUILayout.EnumPopup("Guide Panel Style", guideStyle);
                if (newGuideStyle != guideStyle || standObj == null || standObjEditor == null)
                {
                    var standPath = newGuideStyle == GuideStyle.Futuristic ? SciFiStandPath : TikiStandPath;
                    standObj       = AssetDatabase.LoadAssetAtPath(GetAssetPath(standPath), typeof(object));
                    standObjEditor = UnityEditor.Editor.CreateEditor(standObj);
                }
                var r = GUILayoutUtility.GetRect(450, 150);
                standObjEditor.OnPreviewGUI(r, EditorStyles.helpBox);
                guideStyle = newGuideStyle;
            }

            UTStyles.RenderSectionHeader("PostProcessing and Collisions");
            UTStyles.RenderNote("Layers are very important to the overall setup. Make sure you follow the instructions below");

            layers.Clear();
            for (int i = 0; i < 32; i++)
            {
                var layerName = LayerMask.LayerToName(i);
                if (layerName.Length > 0)
                {
                    layers.Add($"[{i}] {layerName}");
                }
                else
                {
                    if (i > 22 && emptyLayer == 0)
                    {
                        emptyLayer = i;
                    }
                    layers.Add($"[{i}] -- not set --");
                }
            }

            var layersArr = layers.ToArray();

            if (emptyLayer != 0)
            {
                if (GUILayout.Button("Setup Layers"))
                {
                    SetupLayers();
                }
                UTStyles.RenderNote("It seems like you have empty layers available, UdonToolkit can set up everything for you if you click the button above");
                UTStyles.HorizontalLine();
            }

            cameraPPLayer = EditorGUILayout.Popup("Camera PP Layer", cameraPPLayer, layersArr);
            UTStyles.RenderNote("This layer will be used for detecting PP volumes for the Camera System");
            if (cameraPPLayer == 22)
            {
                EditorGUILayout.HelpBox("It is crucial to not put Camera PP volumes on the same layer as the main PostProcessing, or your own view will be affected by the camera effects", MessageType.Warning);
            }

            if (setup)
            {
                var oldColor = GUI.backgroundColor;
                GUI.backgroundColor = Color.green;
                UTStyles.RenderNote("Camera system has been set up in the scene!");
                GUI.backgroundColor = oldColor;
            }
            if (GUILayout.Button("Create Camera System", GUILayout.Height(30)))
            {
                RunCameraSetup();
            }

            if (GUILayout.Button("Add Guide Stand Only", GUILayout.Height(20)))
            {
                AddGuide();
            }
        }
예제 #2
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;
            }
        }
예제 #3
0
 private void OnGUI()
 {
     UTStyles.RenderHeader("Camera System Setup");
     EditorGUILayout.HelpBox("Camera System requires PostProcessing, please install it by searching for PostProcessing in Window -> Package Manager", MessageType.Error);
 }
예제 #4
0
        public override void OnInspectorGUI()
        {
            t = (UdonSharpBehaviour)target;

            showUdonSettings = (bool)(UTUtils.GetUTSetting("showUdonSettings", UTUtils.UTSettingType.Bool) ?? false);

            // we force-disable collision transfer for toolkit driven behaviours as it is not applicable
            if (!nonUBChecked)
            {
                nonUBMode    = t.gameObject.GetComponent <UdonBehaviour>() == null;
                nonUBChecked = true;
            }

            if (!nonUBMode)
            {
                if (UdonSharpEditorUtility.GetBackingUdonBehaviour(t).AllowCollisionOwnershipTransfer)
                {
                    UdonSharpEditorUtility.GetBackingUdonBehaviour(t).AllowCollisionOwnershipTransfer = false;
                }
            }

            var headerExited = false;

            EditorGUI.BeginChangeCheck();
            showUdonSettings = GUILayout.Toggle(showUdonSettings, "Udon Settings", UTStyles.smallButton);
            if (EditorGUI.EndChangeCheck())
            {
                UTUtils.SetUTSetting("showUdonSettings", UTUtils.UTSettingType.Bool, showUdonSettings);
            }

            if (showUdonSettings)
            {
                headerExited = UdonSharpGUI.DrawDefaultUdonSharpBehaviourHeader(t, true);
            }

            if (headerExited)
            {
                return;
            }

            #region Caching

            if (!cacheBuilt)
            {
                tT           = t.GetType();
                programAsset = UdonSharpEditorUtility.GetUdonSharpProgramAsset(t);
                behInfo      = new UTBehaviourInfo(t);

                var prop = serializedObject.GetIterator();
                var next = prop.NextVisible(true);

                if (next)
                {
                    do
                    {
                        if (prop.name == "m_Script")
                        {
                            continue;
                        }

                        if (!fieldCache.ContainsKey(prop.name))
                        {
                            var newField = new UTField(prop);
                            fieldCache.Add(prop.name, newField);
                            if (newField.isInTabGroup)
                            {
                                if (!tabs.ContainsKey(newField.tabGroupName))
                                {
                                    tabs.Add(newField.tabGroupName, new Dictionary <string, UTFieldType>());
                                    // we only support one tab group per behaviour right now
                                    if (!tabsExist)
                                    {
                                        fieldOrder.Add(newField.tabGroupName, UTFieldType.Tab);
                                        tabsExist = true;
                                    }
                                }

                                // since tabs can host foldouts - we need to explicitly retarget them
                                // this logic could be generalized if i ever want to make all of this recursive
                                if (newField.isInFoldout)
                                {
                                    if (!foldouts.ContainsKey(newField.foldoutName))
                                    {
                                        foldouts.Add(newField.foldoutName, new Dictionary <string, UTFieldType>());
                                        tabs[newField.tabGroupName].Add(newField.foldoutName, UTFieldType.Foldout);
                                    }

                                    AddToFieldOrder(newField, prop, true);
                                    continue;
                                }

                                AddToFieldOrder(newField, prop, addToTabGroup: true);
                                continue;
                            }

                            if (newField.isInFoldout)
                            {
                                if (!foldouts.ContainsKey(newField.foldoutName))
                                {
                                    foldouts.Add(newField.foldoutName, new Dictionary <string, UTFieldType>());
                                    fieldOrder.Add(newField.foldoutName, UTFieldType.Foldout);
                                }

                                AddToFieldOrder(newField, prop, true);
                                continue;
                            }

                            AddToFieldOrder(newField, prop);
                        }
                    } while (prop.NextVisible(false));
                }

                cacheBuilt = true;
                return;
            }

            var e = Event.current;
            if (e.type == EventType.Repaint)
            {
                if (firstRepaint)
                {
                    firstRepaint = false;
                    return;
                }
            }

            #endregion

            if (behInfo.customName != null || behInfo.helpUrl != null)
            {
                EditorGUILayout.BeginHorizontal();
                UTStyles.RenderHeader(behInfo.customName != null ? behInfo.customName : behInfo.name);
                if (behInfo.helpUrl != null)
                {
                    if (GUILayout.Button("?", GUILayout.Height(26), GUILayout.Width(26)))
                    {
                        Application.OpenURL(behInfo.helpUrl);
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            if (behInfo.helpMsg != null)
            {
                UTStyles.RenderNote(behInfo.helpMsg);
            }

            if (behInfo.onBeforeEditor != null)
            {
                behInfo.onBeforeEditor.Invoke(t, new object[] { serializedObject });
            }

            // handle jagged arrays
            Undo.RecordObject(t, "Change Properties");

            EditorGUI.BeginChangeCheck();
            droppedObjects = false;

            // this method is overrideable by custom code
            DrawGUI();

            if (EditorGUI.EndChangeCheck() || droppedObjects || shouldReserialize)
            {
                if (behInfo.onValuesChanged != null)
                {
                    behInfo.onValuesChanged.Invoke(t, new object[] { serializedObject });
                }
                serializedObject.ApplyModifiedProperties();
            }

            if (droppedObjects)
            {
                return;
            }

            if (behInfo.onAfterEditor != null)
            {
                behInfo.onAfterEditor.Invoke(t, new object[] { serializedObject });
            }

            #region Buttons
            if (behInfo.buttons != null && !Application.isPlaying && behInfo.buttons.Length > 0)
            {
                buttonsExpanded = UTStyles.FoldoutHeader("Editor Methods", buttonsExpanded);
                if (buttonsExpanded)
                {
                    EditorGUILayout.BeginVertical(new GUIStyle("helpBox"));
                    foreach (var button in behInfo.buttons)
                    {
                        if (GUILayout.Button(button.Name))
                        {
                            button.Invoke(t, new object[] {});
                        }
                    }
                    EditorGUILayout.EndVertical();
                }
            }
            if (Application.isPlaying && behInfo.udonCustomEvents.Length > 0 && !nonUBMode)
            {
                methodsExpanded = UTStyles.FoldoutHeader("Udon Events", methodsExpanded);
                if (methodsExpanded)
                {
                    EditorGUILayout.BeginVertical(new GUIStyle("helpBox"));
                    var rowBreak = Mathf.Max(1, Mathf.Min(3, behInfo.udonCustomEvents.Length - 1));
                    var rowEndI  = -100;
                    foreach (var(button, i) in behInfo.udonCustomEvents.WithIndex())
                    {
                        if (i == rowEndI && i != behInfo.udonCustomEvents.Length - 1)
                        {
                            EditorGUILayout.EndHorizontal();
                        }
                        if (i % rowBreak == 0 && i != behInfo.udonCustomEvents.Length - 1)
                        {
                            EditorGUILayout.BeginHorizontal();
                            rowEndI = Math.Min(i + rowBreak, behInfo.udonCustomEvents.Length - 1);
                        }
                        if (GUILayout.Button(button))
                        {
                            UdonSharpEditorUtility.GetBackingUdonBehaviour(t).SendCustomEvent(button);
                            UdonSharpEditorUtility.CopyUdonToProxy(t);
                        }
                        if (i == behInfo.udonCustomEvents.Length - 1 && rowEndI != -100)
                        {
                            EditorGUILayout.EndHorizontal();
                        }
                    }
                    EditorGUILayout.EndVertical();
                }
            }
            #endregion
        }