public override void OnInspectorGUI()
        {
            RenderProfileHeader(ProfileTitle, ProfileDescription, target);

            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                serializedObject.Update();

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Mixed Reality Capture Settings (Experimental)", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(MRCDocURL);
                }
                EditorGUILayout.HelpBox("Render from PV Camera is supported on Unity 2018.4.13f1 or newer and 2019.3.0f1 or newer. Enabling the feature on other versions may result in incorrect capture behavior.", MessageType.Info);
                EditorGUILayout.PropertyField(renderFromPVCameraForMixedRealityCapture, pvCameraRenderingTitle);

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Depth Reprojection Settings", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(DepthReprojectionDocURL);
                }
                EditorGUILayout.PropertyField(reprojectionMethod, reprojectionMethodTitle);

                serializedObject.ApplyModifiedProperties();
            }
        }
        public override void OnInspectorGUI()
        {
            RenderProfileHeader(ProfileTitle, ProfileDescription, target);

            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                serializedObject.Update();

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Mixed Reality Capture Settings (Experimental)", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(MRCDocURL);
                }
                EditorGUILayout.HelpBox("Render from PV camera is supported in Unity 2018.4.13 and newer if using Unity 2018, and in Unity 2019.4.9f1 and newer if using Unity 2019. Enabling the feature on other versions may result in incorrect capture behavior.", MessageType.Info);
                EditorGUILayout.HelpBox("This doesn't work on XR SDK when we shipped this MRTK release. See this page for the latest information: https://github.com/microsoft/MixedRealityToolkit-Unity/issues/8707", MessageType.Info);
                EditorGUILayout.PropertyField(renderFromPVCameraForMixedRealityCapture, pvCameraRenderingTitle);

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Depth Reprojection Settings", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(DepthReprojectionDocURL);
                }
                EditorGUILayout.PropertyField(reprojectionMethod, reprojectionMethodTitle);

                serializedObject.ApplyModifiedProperties();
            }
        }
Example #3
0
        /// <summary>
        /// Render the custom properties for the Leap Motion profile
        /// </summary>
        public virtual void RenderCustomInspector()
        {
            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                // Add the documentation help button
                using (new EditorGUILayout.HorizontalScope())
                {
                    // Draw an empty title to align the documentation button to the right
                    InspectorUIUtility.DrawLabel("", InspectorUIUtility.DefaultFontSize, InspectorUIUtility.ColorTint10);

                    InspectorUIUtility.RenderDocumentationButton(leapDocURL);
                }

                // Show warning if the leap core assets are not in the project
                if (!LeapMotionUtilities.IsLeapInProject)
                {
                    EditorGUILayout.HelpBox("The Leap Motion Core Assets could not be found in your project. For more information, visit the Leap Motion MRTK documentation.", MessageType.Error);
                }
                else
                {
                    serializedObject.Update();

                    EditorGUILayout.PropertyField(leapControllerOrientation);

                    if (instance.LeapControllerOrientation == LeapControllerOrientation.Desk)
                    {
                        EditorGUILayout.PropertyField(leapControllerOffset);
                    }
                    else if (instance.LeapControllerOrientation == LeapControllerOrientation.Headset)
                    {
                        // Allow selection of the LeapVRDeviceOffsetMode if the LeapControllerOrientation is Headset
                        EditorGUILayout.PropertyField(leapVRDeviceOffsetMode);

                        if (leapVRDeviceOffsetMode.enumValueIndex == (int)LeapVRDeviceOffsetMode.ManualHeadOffset)
                        {
                            // Display the properties for editing the head offset
                            EditorGUILayout.PropertyField(leapVRDeviceOffsetY);
                            EditorGUILayout.PropertyField(leapVRDeviceOffsetZ);
                            EditorGUILayout.PropertyField(leapVRDeviceOffsetTiltX);
                        }
                        else if (leapVRDeviceOffsetMode.enumValueIndex == (int)LeapVRDeviceOffsetMode.Transform)
                        {
                            // Display the transform property
                            // EditorGUILayout.PropertyField() did not allow the setting the transform property in editor
                            leapVRDeviceOriginTransform = EditorGUILayout.ObjectField("Leap VR Device Origin", leapVRDeviceOrigin.objectReferenceValue, typeof(Transform), true) as Transform;

                            instance.LeapVRDeviceOrigin = leapVRDeviceOriginTransform;
                        }
                    }

                    // Display pinch thresholds
                    EditorGUILayout.PropertyField(enterPinchDistance);
                    EditorGUILayout.PropertyField(exitPinchDistance);

                    serializedObject.ApplyModifiedProperties();
                }
            }
        }
Example #4
0
 private static void BuildTitle(string title, string url, Texture titleIcon = null)
 {
     EditorGUILayout.LabelField(string.Empty, GUI.skin.horizontalSlider);
     // Section Title
     EditorGUILayout.BeginHorizontal();
     EditorGUILayout.LabelField(new GUIContent(title, titleIcon), EditorStyles.boldLabel);
     InspectorUIUtility.RenderDocumentationButton(url);
     EditorGUILayout.EndHorizontal();
 }
Example #5
0
        private void RenderToolboxItem(ToolboxItem item, bool requiresCanvas = false)
        {
            if (item == null || item.Prefab == null)
            {
                return;
            }

            var buttonContent = new GUIContent()
            {
                image   = item.Icon,
                text    = string.Empty,
                tooltip = item.DocURL,
            };

            using (new EditorGUILayout.VerticalScope())
            {
                using (new EditorGUILayout.HorizontalScope())
                {
                    GUILayout.FlexibleSpace();
                    // If this component requires an MRTK canvas but none are present, disable the button.
                    using (new EditorGUI.DisabledGroupScope(requiresCanvas && canvasUtilities.Length == 0))
                    {
                        if (GUILayout.Button(buttonContent, GUILayout.MaxHeight(ToolboxItemHeight), GUILayout.Width(ToolboxItemButtonWidth)))
                        {
                            Selection.activeObject = !requiresCanvas?Instantiate(item.Prefab) : Instantiate(item.Prefab, canvasUtilities[dropdownIndex].transform);

                            Undo.RegisterCreatedObjectUndo(Selection.activeObject, $"Create {item.Name} Object");
                        }
                    }
                    GUILayout.FlexibleSpace();
                }

                using (new EditorGUILayout.HorizontalScope())
                {
                    GUILayout.FlexibleSpace();
                    if (!string.IsNullOrEmpty(item.DocURL))
                    {
                        InspectorUIUtility.RenderDocumentationButton(item.DocURL, ToolboxItemButtonWidth);
                    }
                    GUILayout.FlexibleSpace();
                }

                using (new EditorGUILayout.HorizontalScope())
                {
                    GUILayout.FlexibleSpace();
                    EditorGUILayout.LabelField(item.Name, centeredStyle, GUILayout.MaxWidth(ToolboxItemWidth));
                    GUILayout.FlexibleSpace();
                }

                EditorGUILayout.Space();
            }
        }
Example #6
0
 private void DrawGeneralSection()
 {
     using (new EditorGUILayout.HorizontalScope())
     {
         EditorGUILayout.LabelField("General", EditorStyles.boldLabel);
         InspectorUIUtility.RenderDocumentationButton(ScrollViewDocURL);
     }
     using (new EditorGUI.IndentLevelScope())
     {
         EditorGUILayout.PropertyField(scrollDirection);
         EditorGUILayout.Space();
     }
 }
        /// <summary>
        /// Draws a documentation link for the service.
        /// </summary>
        protected void RenderDocumentation(Object profileObject)
        {
            if (profileObject == null)
            {   // Can't proceed if profile is null.
                return;
            }

            HelpURLAttribute helpURL = profileObject.GetType().GetCustomAttribute <HelpURLAttribute>();

            if (helpURL != null)
            {
                InspectorUIUtility.RenderDocumentationButton(helpURL.URL);
            }
        }
Example #8
0
        private void DrawHeader()
        {
            MixedRealityInspectorUtility.RenderMixedRealityToolkitLogo();

            using (new EditorGUILayout.HorizontalScope())
            {
                EditorGUILayout.LabelField("Migration Window", EditorStyles.boldLabel);
                InspectorUIUtility.RenderDocumentationButton(MigrationWindowURL);
            }
            EditorGUILayout.LabelField(WindowDescription, EditorStyles.wordWrappedLabel);

            EditorGUILayout.Space();
            EditorGUILayout.Space();
        }
Example #9
0
        private void OnGUI()
        {
            windowScrollPosition = EditorGUILayout.BeginScrollView(windowScrollPosition);

            MixedRealityInspectorUtility.RenderMixedRealityToolkitLogo();

            // Render Title
            using (new EditorGUILayout.HorizontalScope())
            {
                EditorGUILayout.LabelField("Mixed Reality Toolkit Optimize Window", MixedRealityStylesUtility.BoldLargeTitleStyle);
                InspectorUIUtility.RenderDocumentationButton(OptimizeWindow_URL);
            }

            EditorGUILayout.LabelField("This tool automates the process of updating your project, currently open scene, and material assets to recommended settings for Mixed Reality", EditorStyles.wordWrappedLabel);
            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Active Build Target: ", EditorUserBuildSettings.activeBuildTarget.ToString());

            PerfTarget = (PerformanceTarget)EditorGUILayout.Popup("Performance Target", (int)this.PerfTarget, PerformanceTargetEnums);
            EditorGUILayout.HelpBox(PerformanceTargetDescriptions[(int)PerfTarget], MessageType.Info);
            EditorGUILayout.Space();

            if (!PlayerSettings.virtualRealitySupported)
            {
                EditorGUILayout.HelpBox("Virtual reality support is not enabled in player settings", MessageType.Error);
                if (GUILayout.Button("Enable Virtual Reality Support"))
                {
                    PlayerSettings.virtualRealitySupported = true;
                }
            }
            else
            {
                selectedToolbarIndex = GUILayout.Toolbar(selectedToolbarIndex, ToolbarTitles);
                if (selectedToolbarIndex == 0)
                {
                    RenderSettingOptimizations();
                }
                else if (selectedToolbarIndex == 1)
                {
                    RenderSceneOptimizations();
                }
                else
                {
                    RenderShaderOptimizations();
                }
            }

            EditorGUILayout.EndScrollView();
        }
        private void DrawSelectNameAndPlatform()
        {
            EditorGUILayout.Space();
            EditorGUILayout.HelpBox("This wizard will help you set up and register a simple extension service. MRTK Services are similar to traditional MonoBehaviour singletons but with more robust access and lifecycle control. Scripts can access services through the MRTK's service provider interface. For more information about services, click the link below.", MessageType.Info);

            using (new EditorGUILayout.HorizontalScope())
            {
                GUILayout.FlexibleSpace();
                InspectorUIUtility.RenderDocumentationButton(servicesDocumentationURL);
                GUILayout.FlexibleSpace();
            }

            EditorGUILayout.Space();
            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Choose a name for your service.", EditorStyles.miniLabel);
            creator.ServiceName = EditorGUILayout.TextField("Service Name", creator.ServiceName);
            creator.ValidateName(errors);
            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Choose which platforms your service will support.", EditorStyles.miniLabel);
            creator.Platforms = (SupportedPlatforms)EditorGUILayout.EnumFlagsField("Platforms", creator.Platforms);
            creator.ValidatePlatforms(errors);
            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Choose a namespace for your service.", EditorStyles.miniLabel);
            creator.Namespace = EditorGUILayout.TextField("Namespace", creator.Namespace);
            creator.ValidateNamespace(errors);
            EditorGUILayout.Space();

            bool hasErrors = errors.Count > 0;

            if (hasErrors)
            {
                RenderErrorLog();
            }

            using (new EditorGUI.DisabledGroupScope(hasErrors))
            {
                if (GUILayout.Button("Next"))
                {
                    creator.Stage = ExtensionServiceCreator.CreationStage.ChooseOutputFolders;
                    creator.StoreState();
                }
            }
        }
        public override void OnInspectorGUI()
        {
            RenderProfileHeader(ProfileTitle, ProfileDescription, target);

            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                serializedObject.Update();

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Depth Reprojection Settings", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(DepthReprojectionDocURL);
                }
                EditorGUILayout.PropertyField(reprojectionMethod, ReprojectionMethodTitle);

                serializedObject.ApplyModifiedProperties();
            }
        }
        private void DrawHeader()
        {
            MixedRealityInspectorUtility.RenderMixedRealityToolkitLogo();

            using (new EditorGUILayout.HorizontalScope())
            {
                EditorGUILayout.LabelField("Migration Window", EditorStyles.boldLabel);
                InspectorUIUtility.RenderDocumentationButton(MigrationWindowURL);
            }
            EditorGUILayout.LabelField(WindowDescription, EditorStyles.wordWrappedLabel);

            // show a warning as long as we're not handling dependencies
            EditorGUILayout.HelpBox("Note that the migration window currently doesn't do dependency checks, " +
                                    "so overrides on prefab instances might be lost after choosing to upgrade. Create a local copy " +
                                    "or make sure to use version control before using the tool on game objects or scenes that are " +
                                    "using prefab overrides.", MessageType.Warning);

            EditorGUILayout.Space();
            EditorGUILayout.Space();
        }
Example #13
0
        public override void OnInspectorGUI()
        {
            RenderProfileHeader(ProfileTitle, ProfileDescription, target);

            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                serializedObject.Update();

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Mixed Reality Capture Settings", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(MRCDocURL);
                }

                EditorGUILayout.HelpBox("On legacy XR, render from PV camera is supported in Unity 2018.4.35f1 and newer if using Unity 2018 and Unity 2019.4.26f1 and newer if using Unity 2019.", MessageType.Info);
                EditorGUILayout.HelpBox("On Windows XR Plugin, render from PV camera is supported in versions 2.8.0, 4.5.0, and 5.3.0 (and newer in each respective major version).", MessageType.Info);
                EditorGUILayout.PropertyField(renderFromPVCameraForMixedRealityCapture, PVCameraRenderingTitle);

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Depth Reprojection Settings", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(DepthReprojectionDocURL);
                }
                EditorGUILayout.PropertyField(reprojectionMethod, ReprojectionMethodTitle);

                EditorGUILayout.Space();
                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUILayout.LabelField("Reading Mode Settings", EditorStyles.boldLabel);
                    InspectorUIUtility.RenderDocumentationButton(ReadingModeDocURL);
                }
                EditorGUILayout.PropertyField(readingModeEnabled);

                serializedObject.ApplyModifiedProperties();
            }
        }
Example #14
0
        /// <summary>
        /// Render the custom properties for the Leap Motion profile
        /// </summary>
        public virtual void RenderCustomInspector()
        {
            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                // Add the documentation help button
                using (new EditorGUILayout.HorizontalScope())
                {
                    // Draw an empty title to align the documentation button to the right
                    InspectorUIUtility.DrawLabel("", InspectorUIUtility.DefaultFontSize, InspectorUIUtility.ColorTint10);

                    InspectorUIUtility.RenderDocumentationButton(leapDocURL);
                }

                // Show warning if the leap core assets are not in the project
                if (!EskyLeapMotionUtilities.IsLeapInProject)
                {
                    EditorGUILayout.HelpBox("The Leap Motion Core Assets could not be found in your project. For more information, visit the Leap Motion MRTK documentation.", MessageType.Error);
                }
                else
                {
                    serializedObject.Update();

                    EditorGUILayout.PropertyField(leapControllerOrientation);

                    if (instance.LeapControllerOrientation == EskyLeapControllerOrientation.Desk)
                    {
                        EditorGUILayout.PropertyField(leapControllerOffset);
                    }

                    EditorGUILayout.PropertyField(enterPinchDistance);

                    EditorGUILayout.PropertyField(exitPinchDistance);

                    serializedObject.ApplyModifiedProperties();
                }
            }
        }
        public override void OnInspectorGUI()
        {
            cb = (ButtonConfigHelper)target;

            bool labelFoldout       = SessionState.GetBool(LabelFoldoutKey, true);
            bool basicEventsFoldout = SessionState.GetBool(BasicEventsFoldoutKey, true);
            bool iconFoldout        = SessionState.GetBool(IconFoldoutKey, true);
            bool showComponents     = SessionState.GetBool(ShowComponentsKey, false);
            bool showSpeechCommand  = SessionState.GetBool(ShowSpeechCommandKey, true);

            if (cb.EditorCheckForCustomIcon())
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    EditorGUILayout.LabelField("Custom Icon Migration", EditorStyles.boldLabel);
                    EditorGUILayout.HelpBox(customIconUpgradeMessage, MessageType.Error);

                    using (new EditorGUILayout.HorizontalScope())
                    {
                        if (GUILayout.Button("Use migration tool to upgrade buttons"))
                        {
                            if (!EditorApplication.ExecuteMenuItem("Mixed Reality/Toolkit/Utilities/Migration Window"))
                            {
                                EditorUtility.DisplayDialog("Package Required", "You need to install the MRTK tools (Microsoft.MixedRealityToolkit.Unity.Tools) package to use the Migration Tool", "OK");
                            }
                        }

                        InspectorUIUtility.RenderDocumentationButton(upgradeDocUrl);
                    }
                }
            }

            showComponents = EditorGUILayout.Toggle("Show Component References", showComponents);

            ButtonIconStyle oldStyle = (ButtonIconStyle)iconStyleProp.intValue;

            using (new EditorGUI.IndentLevelScope(1))
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    labelFoldout = EditorGUILayout.Foldout(labelFoldout, "Labels", true);

                    if (labelFoldout)
                    {
                        EditorGUI.BeginChangeCheck();

                        if (showComponents)
                        {
                            EditorGUILayout.PropertyField(mainLabelTextProp);
                        }

                        if (mainLabelTextProp.objectReferenceValue != null)
                        {
                            Component mainLabelText       = (Component)mainLabelTextProp.objectReferenceValue;
                            bool      mainLabelTextActive = EditorGUILayout.Toggle("Enable Main Label", mainLabelText.gameObject.activeSelf);
                            if (mainLabelText.gameObject.activeSelf != mainLabelTextActive)
                            {
                                mainLabelText.gameObject.SetActive(mainLabelTextActive);
                                EditorUtility.SetDirty(mainLabelText.gameObject);
                            }
                            if (mainLabelText.gameObject.activeSelf)
                            {
                                SerializedObject   labelTextObject = new SerializedObject(mainLabelText);
                                SerializedProperty textProp        = labelTextObject.FindProperty("m_text");
                                EditorGUILayout.PropertyField(textProp, new GUIContent("Main Label Text"));
                                EditorGUILayout.Space();

                                if (EditorGUI.EndChangeCheck())
                                {
                                    labelTextObject.ApplyModifiedProperties();
                                }
                            }
                        }

                        if (showComponents)
                        {
                            EditorGUILayout.PropertyField(seeItSayItLabelProp);
                        }

                        if (seeItSayItLabelProp.objectReferenceValue != null)
                        {
                            GameObject seeItSayItLabel       = (GameObject)seeItSayItLabelProp.objectReferenceValue;
                            bool       seeItSayItLabelActive = EditorGUILayout.Toggle("Enable See it / Say it Label", seeItSayItLabel.activeSelf);
                            if (seeItSayItLabel.activeSelf != seeItSayItLabelActive)
                            {
                                seeItSayItLabel.SetActive(seeItSayItLabelActive);
                                EditorUtility.SetDirty(seeItSayItLabel);
                            }

                            if (seeItSayItLabel.activeSelf)
                            {
                                var sisiChanged = false;
                                EditorGUI.BeginChangeCheck();

                                if (showComponents)
                                {
                                    EditorGUILayout.PropertyField(seeItSayItLabelTextProp);
                                }

                                showSpeechCommand = EditorGUILayout.Toggle("Display Speech Command", showSpeechCommand);

                                SerializedObject   sisiLabelTextObject = new SerializedObject(seeItSayItLabelTextProp.objectReferenceValue);
                                SerializedProperty sisiTextProp        = sisiLabelTextObject.FindProperty("m_text");
                                if (!showSpeechCommand)
                                {
                                    EditorGUILayout.PropertyField(sisiTextProp, new GUIContent("See it / Say it Label"));
                                    EditorGUILayout.Space();
                                }
                                else
                                {
                                    if (interactableProp.objectReferenceValue != null)
                                    {
                                        SerializedObject   interactableObject   = new SerializedObject(interactableProp.objectReferenceValue);
                                        SerializedProperty voiceCommandProperty = interactableObject.FindProperty("voiceCommand");

                                        if (string.IsNullOrEmpty(voiceCommandProperty.stringValue))
                                        {
                                            EditorGUILayout.HelpBox("No valid speech command provided to the interactable", MessageType.Warning);
                                        }
                                        else
                                        {
                                            string sisiText = string.Format("Say \"{0}\"", voiceCommandProperty.stringValue);
                                            if (sisiTextProp.stringValue != sisiText)
                                            {
                                                sisiTextProp.stringValue = sisiText;
                                                sisiChanged = true;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        EditorGUILayout.HelpBox("There is no interactable linked to the button config helper. One is needed to display the appropriate speech command", MessageType.Warning);
                                    }
                                }
                                sisiChanged |= EditorGUI.EndChangeCheck();

                                if (sisiChanged)
                                {
                                    sisiLabelTextObject.ApplyModifiedProperties();
                                }
                            }
                        }
                    }
                }
            }

            using (new EditorGUI.IndentLevelScope(1))
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    basicEventsFoldout = EditorGUILayout.Foldout(basicEventsFoldout, "Basic Events", true);

                    if (basicEventsFoldout)
                    {
                        EditorGUI.BeginChangeCheck();

                        if (showComponents)
                        {
                            EditorGUILayout.PropertyField(interactableProp);
                        }

                        if (interactableProp.objectReferenceValue != null)
                        {
                            SerializedObject   interactableObject = new SerializedObject(interactableProp.objectReferenceValue);
                            SerializedProperty onClickProp        = interactableObject.FindProperty("OnClick");
                            EditorGUILayout.PropertyField(onClickProp);

                            if (EditorGUI.EndChangeCheck())
                            {
                                interactableObject.ApplyModifiedProperties();
                            }
                        }
                    }
                }
            }

            using (new EditorGUI.IndentLevelScope(1))
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    iconFoldout = EditorGUILayout.Foldout(iconFoldout, "Icon", true);
                    ButtonIconSet iconSet = (ButtonIconSet)iconSetProp.objectReferenceValue;

                    if (iconFoldout)
                    {
                        EditorGUILayout.PropertyField(iconStyleProp);

                        switch (cb.IconStyle)
                        {
                        case ButtonIconStyle.Char:
                            DrawIconCharEditor(showComponents, iconSet);
                            break;

                        case ButtonIconStyle.Quad:
                            DrawIconQuadEditor(showComponents, iconSet);
                            break;

                        case ButtonIconStyle.Sprite:
                            DrawIconSpriteEditor(showComponents, iconSet);
                            break;
                        }

                        EditorGUILayout.Space();
                    }
                }
            }

            SessionState.SetBool(LabelFoldoutKey, labelFoldout);
            SessionState.SetBool(BasicEventsFoldoutKey, basicEventsFoldout);
            SessionState.SetBool(IconFoldoutKey, iconFoldout);
            SessionState.SetBool(ShowComponentsKey, showComponents);
            SessionState.SetBool(ShowSpeechCommandKey, showSpeechCommand);

            serializedObject.ApplyModifiedProperties();

            if (oldStyle != (ButtonIconStyle)iconStyleProp.intValue)
            {
                cb.ForceRefresh();
            }
        }
        protected void RenderGeneralSettings()
        {
            Rect position;
            bool isPlayMode = EditorApplication.isPlaying || EditorApplication.isPaused;

            using (new EditorGUILayout.HorizontalScope())
            {
                InspectorUIUtility.DrawTitle("General");

                if (target != null)
                {
                    var helpURL = target.GetType().GetCustomAttribute <HelpURLAttribute>();
                    if (helpURL != null)
                    {
                        InspectorUIUtility.RenderDocumentationButton(helpURL.URL);
                    }
                }
            }

            EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            // States
            // If states value is not provided, try to use Default states type
            if (statesProperty.objectReferenceValue == null)
            {
                statesProperty.objectReferenceValue = ThemeInspector.GetDefaultInteractableStates();
            }

            GUI.enabled = !isPlayMode;
            EditorGUILayout.PropertyField(statesProperty, new GUIContent("States", "The States this Interactable is based on"));
            GUI.enabled = true;

            if (statesProperty.objectReferenceValue == null)
            {
                InspectorUIUtility.DrawError("Please assign a States object!");
                serializedObject.ApplyModifiedProperties();
                return;
            }

            EditorGUILayout.PropertyField(enabledProperty, new GUIContent("Enabled", "Is this Interactable Enabled?"));

            // Input Actions
            bool validActionOptions = inputActionOptions != null;

            GUI.enabled = validActionOptions && !isPlayMode;

            var actionOptions = validActionOptions ? inputActionOptions : new string[] { "Missing Mixed Reality Toolkit" };

            DrawDropDownProperty(EditorGUILayout.GetControlRect(), actionId, actionOptions, InputActionsLabel);

            GUI.enabled = true;

            using (new EditorGUI.IndentLevelScope())
            {
                EditorGUILayout.PropertyField(isGlobal, new GUIContent("Is Global", "Like a modal, does not require focus"));
            }

            // Speech keywords
            bool validSpeechKeywords = speechKeywordOptions != null;

            GUI.enabled = validSpeechKeywords && !isPlayMode;

            string[] keywordOptions = validSpeechKeywords ? speechKeywordOptions : new string[] { "Missing Speech Commands" };
            int      currentIndex   = validSpeechKeywords ? SpeechKeywordLookup(voiceCommands.stringValue, speechKeywordOptions) : 0;

            position = EditorGUILayout.GetControlRect();

            //BeginProperty allows tracking of serialized properties for bolding prefab changes etc
            EditorGUI.BeginProperty(position, SpeechComamndsLabel, voiceCommands);
            {
                currentIndex = EditorGUI.Popup(position, SpeechComamndsLabel.text, currentIndex, keywordOptions);
                if (validSpeechKeywords)
                {
                    voiceCommands.stringValue = currentIndex > 0 ? speechKeywordOptions[currentIndex] : string.Empty;
                }
            }
            EditorGUI.EndProperty();
            GUI.enabled = true;

            // show requires gaze because voice command has a value
            if (!string.IsNullOrEmpty(voiceCommands.stringValue))
            {
                using (new EditorGUI.IndentLevelScope())
                {
                    SerializedProperty requireGaze = serializedObject.FindProperty("RequiresFocus");
                    EditorGUILayout.PropertyField(requireGaze, new GUIContent("Requires Focus", "Does the voice command require gazing at this interactable?"));
                }
            }

            // should be 1 or more
            dimensions.intValue = Mathf.Clamp(dimensions.intValue, 1, 9);
            string[] selectionModeNames = Enum.GetNames(typeof(SelectionModes));
            // clamp to values in the enum
            int selectionModeIndex = Mathf.Clamp(dimensions.intValue, 1, selectionModeNames.Length) - 1;

            // user-friendly dimension settings
            SelectionModes selectionMode = SelectionModes.Button;

            position    = EditorGUILayout.GetControlRect();
            GUI.enabled = !isPlayMode;
            EditorGUI.BeginProperty(position, selectionModeLabel, dimensions);
            {
                selectionMode = (SelectionModes)EditorGUI.EnumPopup(position, selectionModeLabel, (SelectionModes)(selectionModeIndex));

                switch (selectionMode)
                {
                case SelectionModes.Button:
                    dimensions.intValue = 1;
                    break;

                case SelectionModes.Toggle:
                    dimensions.intValue = 2;
                    break;

                case SelectionModes.MultiDimension:
                    // multi dimension mode - set min value to 3
                    dimensions.intValue = Mathf.Max(3, dimensions.intValue);
                    position            = EditorGUILayout.GetControlRect();
                    dimensions.intValue = EditorGUI.IntField(position, dimensionsLabel, dimensions.intValue);
                    break;

                default:
                    break;
                }
            }
            EditorGUI.EndProperty();

            if (dimensions.intValue > 1)
            {
                // toggle or multi dimensional button
                using (new EditorGUI.IndentLevelScope())
                {
                    EditorGUILayout.PropertyField(canSelect, new GUIContent("Can Select", "The user can toggle this button"));
                    EditorGUILayout.PropertyField(canDeselect, new GUIContent("Can Deselect", "The user can untoggle this button, set false for a radial interaction."));

                    position = EditorGUILayout.GetControlRect();
                    EditorGUI.BeginProperty(position, startDimensionLabel, startDimensionIndex);
                    {
                        if (dimensions.intValue >= selectionModeNames.Length)
                        {
                            // multi dimensions
                            if (!isPlayMode)
                            {
                                startDimensionIndex.intValue = EditorGUI.IntField(position, startDimensionLabel, startDimensionIndex.intValue);
                            }
                            else
                            {
                                EditorGUI.IntField(position, CurrentDimensionLabel, dimensionIndex.intValue);
                            }
                        }
                        else if (dimensions.intValue == (int)SelectionModes.Toggle + 1)
                        {
                            if (!isPlayMode)
                            {
                                bool isToggled = EditorGUI.Toggle(position, isToggledLabel, startDimensionIndex.intValue > 0);
                                startDimensionIndex.intValue = isToggled ? 1 : 0;
                            }
                            else
                            {
                                bool isToggled = EditorGUI.Toggle(position, isToggledLabel, dimensionIndex.intValue > 0);
                            }
                        }

                        startDimensionIndex.intValue = Mathf.Clamp(startDimensionIndex.intValue, 0, dimensions.intValue - 1);
                    }
                    EditorGUI.EndProperty();
                }
            }
            GUI.enabled = true;

            EditorGUILayout.EndVertical();
        }
        protected void RenderGeneralSettings()
        {
            Rect position;

            using (new EditorGUILayout.HorizontalScope())
            {
                InspectorUIUtility.DrawLabel("General", InspectorUIUtility.TitleFontSize, InspectorUIUtility.ColorTint10);

                if (target != null)
                {
                    var helpURL = target.GetType().GetCustomAttribute <HelpURLAttribute>();
                    if (helpURL != null)
                    {
                        InspectorUIUtility.RenderDocumentationButton(helpURL.URL);
                    }
                }
            }

            using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
            {
                // If states value is not provided, try to use Default states type
                if (statesProperty.objectReferenceValue == null)
                {
                    statesProperty.objectReferenceValue = GetDefaultInteractableStatesFile();
                }

                EditorGUILayout.PropertyField(statesProperty, new GUIContent("States"));

                if (statesProperty.objectReferenceValue == null)
                {
                    InspectorUIUtility.DrawError("Please assign a States object!");
                    serializedObject.ApplyModifiedProperties();
                    return;
                }

                EditorGUILayout.PropertyField(enabledProperty, new GUIContent("Enabled"));

                // Input Actions
                bool validActionOptions = inputActionOptions != null;
                using (new EditorGUI.DisabledScope(!validActionOptions))
                {
                    var actionOptions = validActionOptions ? inputActionOptions : new string[] { "Missing Mixed Reality Toolkit" };
                    DrawDropDownProperty(EditorGUILayout.GetControlRect(), actionId, actionOptions, InputActionsLabel);
                }

                using (new EditorGUI.IndentLevelScope())
                {
                    EditorGUILayout.PropertyField(isGlobal, new GUIContent("Is Global"));
                }

                // Speech keywords
                bool validSpeechKeywords = speechKeywordOptions != null;
                using (new EditorGUI.DisabledScope(!validSpeechKeywords))
                {
                    string[] keywordOptions = validSpeechKeywords ? speechKeywordOptions : new string[] { "Missing Speech Commands" };
                    int      currentIndex   = validSpeechKeywords ? SpeechKeywordLookup(voiceCommands.stringValue, speechKeywordOptions) : 0;
                    position = EditorGUILayout.GetControlRect();

                    // BeginProperty allows tracking of serialized properties for bolding prefab changes etc
                    using (new EditorGUI.PropertyScope(position, SpeechComamndsLabel, voiceCommands))
                    {
                        currentIndex = EditorGUI.Popup(position, SpeechComamndsLabel.text, currentIndex, keywordOptions);
                        if (validSpeechKeywords)
                        {
                            voiceCommands.stringValue = currentIndex > 0 ? speechKeywordOptions[currentIndex] : string.Empty;
                        }
                    }
                }

                // show requires gaze because voice command has a value
                if (!string.IsNullOrEmpty(voiceCommands.stringValue))
                {
                    using (new EditorGUI.IndentLevelScope())
                    {
                        SerializedProperty requireGaze = serializedObject.FindProperty("voiceRequiresFocus");
                        EditorGUILayout.PropertyField(requireGaze, VoiceRequiresFocusLabel);
                    }
                }

                // should be 1 or more
                dimensions.intValue = Mathf.Clamp(dimensions.intValue, 1, 9);

                // user-friendly dimension settings
                SelectionModes selectionMode = SelectionModes.Button;
                position = EditorGUILayout.GetControlRect();
                using (new EditorGUI.PropertyScope(position, selectionModeLabel, dimensions))
                {
                    // Show enum popup for selection mode, hide option to select SelectionModes.Invalid
                    selectionMode = (SelectionModes)EditorGUI.EnumPopup(position, selectionModeLabel,
                                                                        Interactable.ConvertToSelectionMode(dimensions.intValue),
                                                                        (value) => { return((SelectionModes)value != SelectionModes.Invalid); });

                    switch (selectionMode)
                    {
                    case SelectionModes.Button:
                        dimensions.intValue = 1;
                        break;

                    case SelectionModes.Toggle:
                        dimensions.intValue = 2;
                        break;

                    case SelectionModes.MultiDimension:
                        // multi dimension mode - set min value to 3
                        dimensions.intValue = Mathf.Max(3, dimensions.intValue);
                        position            = EditorGUILayout.GetControlRect();
                        dimensions.intValue = EditorGUI.IntField(position, dimensionsLabel, dimensions.intValue);
                        break;

                    default:
                        break;
                    }
                }

                if (dimensions.intValue > 1)
                {
                    // toggle or multi dimensional button
                    using (new EditorGUI.IndentLevelScope())
                    {
                        EditorGUILayout.PropertyField(canSelect, new GUIContent("Can Select", "The user can toggle this button"));
                        EditorGUILayout.PropertyField(canDeselect, new GUIContent("Can Deselect", "The user can untoggle this button, set false for a radial interaction."));

                        position = EditorGUILayout.GetControlRect();
                        using (new EditorGUI.PropertyScope(position, startDimensionLabel, startDimensionIndex))
                        {
                            var mode = Interactable.ConvertToSelectionMode(dimensions.intValue);
                            if (mode == SelectionModes.Toggle)
                            {
                                bool isToggled = EditorGUI.Toggle(position, isToggledLabel, startDimensionIndex.intValue > 0);
                                startDimensionIndex.intValue = isToggled ? 1 : 0;
                            }
                            else if (mode == SelectionModes.MultiDimension)
                            {
                                startDimensionIndex.intValue = EditorGUI.IntField(position, startDimensionLabel, startDimensionIndex.intValue);
                            }

                            startDimensionIndex.intValue = Mathf.Clamp(startDimensionIndex.intValue, 0, dimensions.intValue - 1);
                        }
                    }
                }
            }
        }
        public override void OnInspectorGUI()
        {
            if (!RenderProfileHeader(ProfileTitle, ProfileDescription, target, true, BackProfileType.Input))
            {
                return;
            }

            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                serializedObject.Update();

                EditorGUILayout.Space();
                EditorGUILayout.PropertyField(pointingExtent);
                EditorGUILayout.PropertyField(defaultRaycastLayerMasks, RaycastLayerMaskContent, true);
                EditorGUILayout.PropertyField(pointerMediator);
                EditorGUILayout.PropertyField(primaryPointerSelector);

                GUIStyle boldFoldout = new GUIStyle(EditorStyles.foldout)
                {
                    fontStyle = FontStyle.Bold
                };

                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Gaze Settings", EditorStyles.boldLabel);
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.PropertyField(gazeCursorPrefab, GazeCursorPrefabContent);
                    EditorGUILayout.PropertyField(gazeProviderType);
                    EditorGUILayout.PropertyField(useHeadGazeOverride);

                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.PropertyField(useEyeTrackingDataWhenAvailable, UseEyeTrackingDataContent);
                    // Render a help link for getting started with eyetracking documentation
                    string helpURL = "https://docs.microsoft.com/windows/mixed-reality/mrtk-unity/features/input/eye-tracking/eye-tracking-basic-setup";
                    InspectorUIUtility.RenderDocumentationButton(helpURL);
                    EditorGUILayout.EndHorizontal();

#if UNITY_2019_3_OR_NEWER
                    if (useEyeTrackingDataWhenAvailable.boolValue && MixedRealityOptimizeUtils.IsBuildTargetUWP() && !PlayerSettings.WSA.GetCapability(PlayerSettings.WSACapability.GazeInput))
                    {
                        EditorGUILayout.HelpBox(EnableGazeCapabilityContent, MessageType.Warning);
                        if (InspectorUIUtility.RenderIndentedButton("Set GazeInput capability"))
                        {
                            PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.GazeInput, true);
                        }
                    }
#endif // UNITY_2019_3_OR_NEWER

                    EditorGUILayout.Space();

                    showGazeProviderProperties = EditorGUILayout.Foldout(showGazeProviderProperties, "Gaze Provider Settings", true, boldFoldout);
                    if (showGazeProviderProperties && CameraCache.Main != null)
                    {
                        var gazeProvider = CameraCache.Main.GetComponent <IMixedRealityGazeProvider>();
                        CreateCachedEditor((Object)gazeProvider, null, ref gazeProviderEditor);

                        // Provide a convenient way to toggle the gaze provider as enabled/disabled via editor
                        gazeProvider.Enabled = EditorGUILayout.Toggle("Enable Gaze Provider", gazeProvider.Enabled);

                        if (gazeProviderEditor != null)
                        {
                            using (new EditorGUI.IndentLevelScope())
                            {
                                // Draw out the rest of the Gaze Provider's settings
                                gazeProviderEditor.OnInspectorGUI();
                            }
                        }
                    }
                }

                EditorGUILayout.Space();
                showPointerOptionProperties = EditorGUILayout.Foldout(showPointerOptionProperties, "Pointer Options", true, boldFoldout);

                if (showPointerOptionProperties)
                {
                    using (new EditorGUI.IndentLevelScope())
                    {
                        RenderPointerList(pointerOptions);
                    }
                }

                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Debug Settings", EditorStyles.boldLabel);
                {
                    EditorGUILayout.PropertyField(debugDrawPointingRays);
                    EditorGUILayout.PropertyField(debugDrawPointingRayColors, true);
                }

                serializedObject.ApplyModifiedProperties();
            }
        }
Example #19
0
        public override void OnInspectorGUI()
        {
            cb = (ButtonConfigHelper)target;

            bool labelFoldout       = SessionState.GetBool(LabelFoldoutKey, true);
            bool basicEventsFoldout = SessionState.GetBool(BasicEventsFoldoutKey, true);
            bool iconFoldout        = SessionState.GetBool(IconFoldoutKey, true);
            bool showComponents     = SessionState.GetBool(ShowComponentsKey, false);

            if (cb.EditorCheckForCustomIcon())
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    EditorGUILayout.LabelField("Custom Icon Migration", EditorStyles.boldLabel);
                    EditorGUILayout.HelpBox(customIconUpgradeMessage, MessageType.Error);

                    using (new EditorGUILayout.HorizontalScope())
                    {
                        if (GUILayout.Button("Use migration tool to upgrade buttons"))
                        {
                            EditorApplication.ExecuteMenuItem("Mixed Reality Toolkit/Utilities/Migration Window");
                        }

                        InspectorUIUtility.RenderDocumentationButton(upgradeDocUrl);
                    }
                }
            }

            showComponents = EditorGUILayout.Toggle("Show Component References", showComponents);

            ButtonIconStyle oldStyle = (ButtonIconStyle)iconStyleProp.enumValueIndex;

            using (new EditorGUI.IndentLevelScope(1))
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    labelFoldout = EditorGUILayout.Foldout(labelFoldout, "Labels", true);

                    if (labelFoldout)
                    {
                        EditorGUI.BeginChangeCheck();

                        if (showComponents)
                        {
                            EditorGUILayout.PropertyField(mainLabelTextProp);
                        }

                        if (mainLabelTextProp.objectReferenceValue != null)
                        {
                            Component mainLabelText       = (Component)mainLabelTextProp.objectReferenceValue;
                            bool      mainLabelTextActive = EditorGUILayout.Toggle("Enable Main Label", mainLabelText.gameObject.activeSelf);
                            if (mainLabelText.gameObject.activeSelf != mainLabelTextActive)
                            {
                                mainLabelText.gameObject.SetActive(mainLabelTextActive);
                                EditorUtility.SetDirty(mainLabelText.gameObject);
                            }
                            if (mainLabelText.gameObject.activeSelf)
                            {
                                SerializedObject   labelTextObject = new SerializedObject(mainLabelText);
                                SerializedProperty textProp        = labelTextObject.FindProperty("m_text");
                                EditorGUILayout.PropertyField(textProp, new GUIContent("Main Label Text"));
                                EditorGUILayout.Space();

                                if (EditorGUI.EndChangeCheck())
                                {
                                    labelTextObject.ApplyModifiedProperties();
                                }
                            }
                        }

                        if (showComponents)
                        {
                            EditorGUILayout.PropertyField(seeItSayItLabelProp);
                        }

                        if (seeItSayItLabelProp.objectReferenceValue != null)
                        {
                            GameObject seeItSayItLabel       = (GameObject)seeItSayItLabelProp.objectReferenceValue;
                            bool       seeItSayItLabelActive = EditorGUILayout.Toggle("Enable See it / Say it Label", seeItSayItLabel.activeSelf);
                            if (seeItSayItLabel.activeSelf != seeItSayItLabelActive)
                            {
                                seeItSayItLabel.SetActive(seeItSayItLabelActive);
                                EditorUtility.SetDirty(seeItSayItLabel.gameObject);
                            }

                            if (seeItSayItLabel.activeSelf)
                            {
                                if (showComponents)
                                {
                                    EditorGUILayout.PropertyField(seeItSatItLabelTextProp);
                                }

                                EditorGUI.BeginChangeCheck();

                                SerializedObject   sisiLabelTextObject = new SerializedObject(seeItSatItLabelTextProp.objectReferenceValue);
                                SerializedProperty sisiTextProp        = sisiLabelTextObject.FindProperty("m_text");
                                EditorGUILayout.PropertyField(sisiTextProp, new GUIContent("See it / Say it Label"));
                                EditorGUILayout.Space();

                                if (EditorGUI.EndChangeCheck())
                                {
                                    sisiLabelTextObject.ApplyModifiedProperties();
                                }
                            }
                        }
                    }
                }
            }

            using (new EditorGUI.IndentLevelScope(1))
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    basicEventsFoldout = EditorGUILayout.Foldout(basicEventsFoldout, "Basic Events", true);

                    if (basicEventsFoldout)
                    {
                        EditorGUI.BeginChangeCheck();

                        if (showComponents)
                        {
                            EditorGUILayout.PropertyField(interactableProp);
                        }

                        SerializedObject   interactableObject = new SerializedObject(interactableProp.objectReferenceValue);
                        SerializedProperty onClickProp        = interactableObject.FindProperty("OnClick");
                        EditorGUILayout.PropertyField(onClickProp);

                        if (EditorGUI.EndChangeCheck())
                        {
                            interactableObject.ApplyModifiedProperties();
                        }
                    }
                }
            }

            using (new EditorGUI.IndentLevelScope(1))
            {
                using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox))
                {
                    iconFoldout = EditorGUILayout.Foldout(iconFoldout, "Icon", true);
                    ButtonIconSet iconSet = (ButtonIconSet)iconSetProp.objectReferenceValue;

                    if (iconFoldout)
                    {
                        EditorGUILayout.PropertyField(iconStyleProp);

                        switch (cb.IconStyle)
                        {
                        case ButtonIconStyle.Char:
                            DrawIconCharEditor(showComponents, iconSet);
                            break;

                        case ButtonIconStyle.Quad:
                            DrawIconQuadEditor(showComponents, iconSet);
                            break;

                        case ButtonIconStyle.Sprite:
                            DrawIconSpriteEditor(showComponents, iconSet);
                            break;
                        }

                        EditorGUILayout.Space();
                    }
                }
            }

            SessionState.SetBool(LabelFoldoutKey, labelFoldout);
            SessionState.SetBool(BasicEventsFoldoutKey, basicEventsFoldout);
            SessionState.SetBool(IconFoldoutKey, iconFoldout);
            SessionState.SetBool(ShowComponentsKey, showComponents);

            serializedObject.ApplyModifiedProperties();

            if (oldStyle != (ButtonIconStyle)iconStyleProp.enumValueIndex)
            {
                cb.ForceRefresh();
            }
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (target != null)
            {
                var helpURL = target.GetType().GetCustomAttribute <HelpURLAttribute>();
                if (helpURL != null)
                {
                    InspectorUIUtility.RenderDocumentationButton(helpURL.URL);
                }
            }

            // Ensure there is a touchable.
            if (touchable == null)
            {
                EditorGUILayout.HelpBox($"{target.GetType().Name} requires a {nameof(NearInteractionTouchableSurface)}-derived component on this game object to function.", MessageType.Warning);

                bool isUnityUI = (button.GetComponent <RectTransform>() != null);
                var  typeToAdd = isUnityUI ? typeof(NearInteractionTouchableUnityUI) : typeof(NearInteractionTouchable);

                if (GUILayout.Button($"Add {typeToAdd.Name} component"))
                {
                    Undo.RecordObject(target, string.Concat($"Add {typeToAdd.Name}"));
                    var addedComponent = button.gameObject.AddComponent(typeToAdd);
                    touchable = (NearInteractionTouchableSurface)addedComponent;
                }
                else
                {
                    // It won't work without it, return to avoid nullrefs.
                    return;
                }
            }

            // Ensure that the touchable has EventsToReceive set to Touch
            if (touchable.EventsToReceive != TouchableEventType.Touch)
            {
                EditorGUILayout.HelpBox($"The {nameof(NearInteractionTouchableSurface)}-derived component on this game object currently has its EventsToReceive set to '{touchable.EventsToReceive}'.  It must be set to 'Touch' in order for PressableButton to function propertly.", MessageType.Warning);

                if (GUILayout.Button("Set EventsToReceive to 'Touch'"))
                {
                    Undo.RecordObject(touchable, string.Concat("Set EventsToReceive to Touch on ", touchable.name));
                    touchable.EventsToReceive = TouchableEventType.Touch;
                }
            }

            EditorGUILayout.Space();
            EditorGUILayout.PropertyField(movingButtonVisuals);

            // Ensure that there is a moving button visuals in the UnityUI case.  Even if it is not visible, it must be present to receive GraphicsRaycasts.
            if (touchable is NearInteractionTouchableUnityUI)
            {
                if (movingButtonVisuals.objectReferenceValue == null)
                {
                    EditorGUILayout.HelpBox($"When used with a NearInteractionTouchableUnityUI, a MovingButtonVisuals is required, as it receives the GraphicsRaycast that allows pressing the button with near/hand interactions.  It does not need to be visible, but it must be able to receive GraphicsRaycasts.", MessageType.Warning);
                }
                else
                {
                    var movingVisualGameObject = (GameObject)movingButtonVisuals.objectReferenceValue;
                    var movingGraphic          = movingVisualGameObject.GetComponentInChildren <UnityEngine.UI.Graphic>();
                    if (movingGraphic == null)
                    {
                        EditorGUILayout.HelpBox($"When used with a NearInteractionTouchableUnityUI, the MovingButtonVisuals must contain an Image, RawImage, or other Graphic element so that it can receive a GraphicsRaycast.", MessageType.Warning);
                    }
                }
            }

            EditorGUILayout.LabelField("Press Settings", EditorStyles.boldLabel);

            EditorGUI.BeginChangeCheck();
            var currentMode = distanceSpaceMode.intValue;

            EditorGUILayout.PropertyField(distanceSpaceMode);
            // EndChangeCheck returns true when something was selected in the dropdown, but
            // doesn't necessarily mean that the value itself changed. Check for that too.
            if (EditorGUI.EndChangeCheck() && currentMode != distanceSpaceMode.intValue)
            {
                // Changing the DistanceSpaceMode requires updating the plane distance values so they stay in the same relative ratio positions
                Undo.RecordObject(target, string.Concat("Trigger Plane Distance Conversion of ", button.name));
                button.DistanceSpaceMode = (PressableButton.SpaceMode)distanceSpaceMode.enumValueIndex;
                serializedObject.Update();
            }

            DrawPropertiesExcluding(serializedObject, excludeProperties);

            startPushDistance.floatValue = ClampStartPushDistance(startPushDistance.floatValue);

            // show button state in play mode
            {
                EditorGUI.BeginDisabledGroup(Application.isPlaying == false);

                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Button State", EditorStyles.boldLabel);
                EditorGUILayout.LabelField("Current Push Distance", button.CurrentPushDistance.ToString());
                EditorGUILayout.Toggle("Touching", button.IsTouching);
                EditorGUILayout.Toggle("Pressing", button.IsPressing);
                EditorGUI.EndDisabledGroup();
            }

            // editor settings
            {
                EditorGUI.BeginDisabledGroup(Application.isPlaying == true);
                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Editor Settings", EditorStyles.boldLabel);
                var prevVisiblePlanes = SessionState.GetBool(VisiblePlanesKey, true);
                VisiblePlanes = EditorGUILayout.Toggle("Show Button Event Planes", prevVisiblePlanes);
                if (VisiblePlanes != prevVisiblePlanes)
                {
                    SessionState.SetBool(VisiblePlanesKey, VisiblePlanes);
                    EditorUtility.SetDirty(target);
                }

                // enable plane editing
                {
                    EditorGUI.BeginDisabledGroup(VisiblePlanes == false);
                    var prevEditingEnabled = SessionState.GetBool(EditingEnabledKey, false);
                    EditingEnabled = EditorGUILayout.Toggle("Make Planes Editable", EditingEnabled);
                    if (EditingEnabled != prevEditingEnabled)
                    {
                        SessionState.SetBool(EditingEnabledKey, EditingEnabled);
                        EditorUtility.SetDirty(target);
                    }
                    EditorGUI.EndDisabledGroup();
                }

                EditorGUI.EndDisabledGroup();
            }

            serializedObject.ApplyModifiedProperties();
        }
Example #21
0
        public override void OnInspectorGUI()
        {
            if (!RenderProfileHeader(ProfileTitle, ProfileDescription, target, true, BackProfileType.Input))
            {
                return;
            }

            using (new EditorGUI.DisabledGroupScope(IsProfileLock((BaseMixedRealityProfile)target)))
            {
                serializedObject.Update();

                EditorGUILayout.Space();
                EditorGUILayout.PropertyField(pointingExtent);
                EditorGUILayout.PropertyField(pointingRaycastLayerMasks, RaycastLayerMaskContent, true);
                EditorGUILayout.PropertyField(pointerMediator);
                EditorGUILayout.PropertyField(primaryPointerSelector);

                GUIStyle boldFoldout = new GUIStyle(EditorStyles.foldout)
                {
                    fontStyle = FontStyle.Bold
                };

                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Gaze Settings", EditorStyles.boldLabel);
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.PropertyField(gazeCursorPrefab, GazeCursorPrefabContent);
                    EditorGUILayout.PropertyField(gazeProviderType);
                    EditorGUILayout.PropertyField(useHeadGazeOverride);

                    EditorGUILayout.BeginHorizontal();
                    EditorGUILayout.PropertyField(useEyeTrackingDataWhenAvailable, UseEyeTrackingDataContent);
                    // Render a help link for getting started with eyetracking documentation
                    string helpURL = "https://docs.microsoft.com/windows/mixed-reality/mrtk-unity/features/input/eye-tracking/eye-tracking-basic-setup";
                    InspectorUIUtility.RenderDocumentationButton(helpURL);
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.Space();

                    var gazeProvider = CameraCache.Main.GetComponent <IMixedRealityGazeProvider>();
                    CreateCachedEditor((Object)gazeProvider, null, ref gazeProviderEditor);

                    showGazeProviderProperties = EditorGUILayout.Foldout(showGazeProviderProperties, "Gaze Provider Settings", true, boldFoldout);
                    if (showGazeProviderProperties && !gazeProviderEditor.IsNull())
                    {
                        gazeProviderEditor.OnInspectorGUI();
                    }
                }

                EditorGUILayout.Space();
                showPointerOptionProperties = EditorGUILayout.Foldout(showPointerOptionProperties, "Pointer Options", true, boldFoldout);

                if (showPointerOptionProperties)
                {
                    using (new EditorGUI.IndentLevelScope())
                    {
                        RenderPointerList(pointerOptions);
                    }
                }


                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Debug Settings", EditorStyles.boldLabel);
                {
                    EditorGUILayout.PropertyField(debugDrawPointingRays);
                    EditorGUILayout.PropertyField(debugDrawPointingRayColors, true);
                }

                serializedObject.ApplyModifiedProperties();
            }
        }