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(); } }
/// <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(); } } }
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(); }
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(); } }
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); } }
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(); }
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(); }
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(); } }
/// <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(); } }
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(); }
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(); } }