예제 #1
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            label.tooltip = VRTK_EditorUtilities.GetTooltipAttribute(fieldInfo).tooltip;
            SerializedProperty xState = property.FindPropertyRelative("xState");
            SerializedProperty yState = property.FindPropertyRelative("yState");
            SerializedProperty zState = property.FindPropertyRelative("zState");

            int indent = EditorGUI.indentLevel;

            EditorGUI.indentLevel = 0;
            position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
            float updatePositionX = position.x;
            float labelWidth      = 15f;
            float fieldWidth      = (position.width / 3f) - labelWidth;

            EditorGUI.LabelField(new Rect(updatePositionX, position.y, labelWidth, position.height), "X");
            updatePositionX += labelWidth;
            xState.boolValue = EditorGUI.Toggle(new Rect(updatePositionX, position.y, fieldWidth, position.height), xState.boolValue);
            updatePositionX += fieldWidth;

            EditorGUI.LabelField(new Rect(updatePositionX, position.y, labelWidth, position.height), "Y");
            updatePositionX += labelWidth;
            yState.boolValue = EditorGUI.Toggle(new Rect(updatePositionX, position.y, fieldWidth, position.height), yState.boolValue);
            updatePositionX += fieldWidth;

            EditorGUI.LabelField(new Rect(updatePositionX, position.y, labelWidth, position.height), "Z");
            updatePositionX += labelWidth;
            zState.boolValue = EditorGUI.Toggle(new Rect(updatePositionX, position.y, fieldWidth, position.height), zState.boolValue);
            updatePositionX += fieldWidth;

            EditorGUI.indentLevel = indent;
        }
예제 #2
0
        public override void OnInspectorGUI()
        {
            EditorGUILayout.PropertyField(distanceLimit);

            _showLayers = EditorGUILayout.Foldout(_showLayers, VRTK_EditorUtilities.BuildGUIContent <VRTK_NavMeshData>("validAreas"));

            if (_showLayers)
            {
                EditorGUI.indentLevel++;
                int      currentAreas = target.validAreas;
                string[] areas        = GameObjectUtility.GetNavMeshAreaNames();
                for (int i = 0; i < areas.Length; i++)
                {
                    var selected = (currentAreas & (1 << i)) != 0;
                    if (EditorGUILayout.Toggle(areas[i], selected))
                    {
                        target.validAreas |= (1 << i);
                    }
                    else
                    {
                        target.validAreas &= ~(1 << i);
                    }
                }
                EditorGUI.indentLevel--;
            }
        }
예제 #3
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            label.tooltip = VRTK_EditorUtilities.GetTooltipAttribute(fieldInfo).tooltip;
            SerializedProperty minimum = property.FindPropertyRelative("minimum");
            SerializedProperty maximum = property.FindPropertyRelative("maximum");

            int indent = EditorGUI.indentLevel;

            EditorGUI.indentLevel = 0;
            position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
            float updatePositionX = position.x;
            float labelWidth      = 30f;
            float fieldWidth      = (position.width / 3f) - labelWidth;

            EditorGUI.LabelField(new Rect(updatePositionX, position.y, labelWidth, position.height), "Min");
            updatePositionX   += labelWidth;
            minimum.floatValue = EditorGUI.FloatField(new Rect(updatePositionX, position.y, fieldWidth, position.height), minimum.floatValue);
            updatePositionX   += fieldWidth;

            EditorGUI.LabelField(new Rect(updatePositionX, position.y, labelWidth, position.height), "Max");
            updatePositionX   += labelWidth;
            maximum.floatValue = EditorGUI.FloatField(new Rect(updatePositionX, position.y, fieldWidth, position.height), maximum.floatValue);
            updatePositionX   += fieldWidth;

            EditorGUI.indentLevel = indent;
        }
예제 #4
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            label.tooltip = VRTK_EditorUtilities.GetTooltipAttribute(fieldInfo).tooltip;
            bool foundGeneric = false;
            bool valid        = false;

            try
            {
                Vector2 input  = SerializedPropertyExtensions.GetValue <Limits2D>(property).AsVector2();
                Vector2 output = BuildSlider(position, label, input, out valid);
                if (valid)
                {
                    SerializedPropertyExtensions.SetValue <Limits2D>(property, new Limits2D(output));
                }
                foundGeneric = true;
            }
            catch (System.Exception)
            {
                Error(position, label);
            }

            if (!foundGeneric)
            {
                switch (property.propertyType)
                {
                case SerializedPropertyType.Vector2:
                    Vector2 input  = property.vector2Value;
                    Vector2 output = BuildSlider(position, label, input, out valid);
                    if (valid)
                    {
                        property.vector2Value = output;
                    }
                    break;

                default:
                    Error(position, label);
                    break;
                }
            }
        }
        public override void OnInspectorGUI()
        {
            VRTK_SDKSetup setup = (VRTK_SDKSetup)target;

            serializedObject.Update();

            using (new EditorGUILayout.VerticalScope("Box"))
            {
                VRTK_EditorUtilities.AddHeader("SDK Selection", false);

                Func <VRTK_SDKInfo, ReadOnlyCollection <VRTK_SDKInfo>, string> sdkNameSelector = (info, installedInfos)
                                                                                                 => info.description.prettyName + (installedInfos.Contains(info) ? "" : SDKNotInstalledDescription);
                string[] availableSystemSDKNames     = VRTK_SDKManager.AvailableSystemSDKInfos.Select(info => sdkNameSelector(info, VRTK_SDKManager.InstalledSystemSDKInfos)).ToArray();
                string[] availableBoundariesSDKNames = VRTK_SDKManager.AvailableBoundariesSDKInfos.Select(info => sdkNameSelector(info, VRTK_SDKManager.InstalledBoundariesSDKInfos)).ToArray();
                string[] availableHeadsetSDKNames    = VRTK_SDKManager.AvailableHeadsetSDKInfos.Select(info => sdkNameSelector(info, VRTK_SDKManager.InstalledHeadsetSDKInfos)).ToArray();
                string[] availableControllerSDKNames = VRTK_SDKManager.AvailableControllerSDKInfos.Select(info => sdkNameSelector(info, VRTK_SDKManager.InstalledControllerSDKInfos)).ToArray();
                string[] availableTrackerSDKNames    = VRTK_SDKManager.AvailableTrackerSDKInfos.Select(info => sdkNameSelector(info, VRTK_SDKManager.InstalledTrackerSDKInfos)).ToArray();
                string[] availableHandSDKNames       = VRTK_SDKManager.AvailableHandSDKInfos.Select(info => sdkNameSelector(info, VRTK_SDKManager.InstalledHandSDKInfos)).ToArray();
                string[] allAvailableSDKNames        = availableSystemSDKNames
                                                       .Concat(availableBoundariesSDKNames)
                                                       .Concat(availableHeadsetSDKNames)
                                                       .Concat(availableControllerSDKNames)
                                                       .Concat(availableTrackerSDKNames)
                                                       .Concat(availableHandSDKNames)
                                                       .Distinct()
                                                       .ToArray();

                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUI.BeginChangeCheck();

                    List <GUIContent> quickSelectOptions = allAvailableSDKNames
                                                           .Select(sdkName => new GUIContent(sdkName))
                                                           .ToList();
                    int quicklySelectedSDKIndex = 0;

                    if (AreAllSDKsTheSame())
                    {
                        quicklySelectedSDKIndex = allAvailableSDKNames
                                                  .ToList()
                                                  .FindIndex(availableSDKName => availableSDKName.Replace(SDKNotInstalledDescription, "")
                                                             == setup.systemSDKInfo.description.prettyName);
                    }
                    else
                    {
                        quickSelectOptions.Insert(0, new GUIContent("Mixed..."));
                    }

                    quicklySelectedSDKIndex = EditorGUILayout.Popup(
                        new GUIContent("Quick Select", "Quickly select one of the SDKs into all slots."),
                        quicklySelectedSDKIndex,
                        quickSelectOptions.ToArray());
                    if (!AreAllSDKsTheSame())
                    {
                        quicklySelectedSDKIndex--;
                    }

                    if (EditorGUI.EndChangeCheck() && (AreAllSDKsTheSame() || quicklySelectedSDKIndex != -1))
                    {
                        string quicklySelectedSDKName = allAvailableSDKNames[quicklySelectedSDKIndex].Replace(SDKNotInstalledDescription, "");

                        Func <VRTK_SDKInfo, bool> predicate = info => info.description.prettyName == quicklySelectedSDKName;
                        VRTK_SDKInfo newSystemSDKInfo       = VRTK_SDKManager.AvailableSystemSDKInfos.FirstOrDefault(predicate);
                        VRTK_SDKInfo newBoundariesSDKInfo   = VRTK_SDKManager.AvailableBoundariesSDKInfos.FirstOrDefault(predicate);
                        VRTK_SDKInfo newHeadsetSDKInfo      = VRTK_SDKManager.AvailableHeadsetSDKInfos.FirstOrDefault(predicate);
                        VRTK_SDKInfo newControllerSDKInfo   = VRTK_SDKManager.AvailableControllerSDKInfos.FirstOrDefault(predicate);
                        VRTK_SDKInfo newTrackerSDKInfo      = VRTK_SDKManager.AvailableTrackerSDKInfos.FirstOrDefault(predicate);
                        VRTK_SDKInfo newHandSDKInfo         = VRTK_SDKManager.AvailableHandSDKInfos.FirstOrDefault(predicate);

                        Undo.RecordObject(setup, "SDK Change (Quick Select)");
                        if (newSystemSDKInfo != null)
                        {
                            setup.systemSDKInfo = newSystemSDKInfo;
                        }
                        if (newBoundariesSDKInfo != null)
                        {
                            setup.boundariesSDKInfo = newBoundariesSDKInfo;
                        }
                        if (newHeadsetSDKInfo != null)
                        {
                            setup.headsetSDKInfo = newHeadsetSDKInfo;
                        }
                        if (newControllerSDKInfo != null)
                        {
                            setup.controllerSDKInfo = newControllerSDKInfo;
                        }
                        if (newTrackerSDKInfo != null)
                        {
                            setup.trackerSDKInfo = newTrackerSDKInfo;
                        }
                        if (newHandSDKInfo != null)
                        {
                            setup.handSDKInfo = newHandSDKInfo;
                        }

                        UpdateDetailedSDKSelectionFoldOut();
                    }

                    if (AreAllSDKsTheSame())
                    {
                        VRTK_SDKInfo selectedInfo = new[]
                        {
                            setup.systemSDKInfo,
                            setup.boundariesSDKInfo,
                            setup.headsetSDKInfo,
                            setup.controllerSDKInfo,
                            setup.trackerSDKInfo,
                            setup.handSDKInfo
                        }.First(info => info != null);
                        DrawVRDeviceNameLabel(selectedInfo, "System, Boundaries, Headset, Controller, Trackers, and Hands", 0);
                    }
                }

                EditorGUI.indentLevel++;

                if (!isDetailedSDKSelectionFoldOut.HasValue)
                {
                    UpdateDetailedSDKSelectionFoldOut();
                }
                isDetailedSDKSelectionFoldOut = EditorGUI.Foldout(
                    EditorGUILayout.GetControlRect(),
                    isDetailedSDKSelectionFoldOut.Value,
                    "Detailed Selection",
                    true
                    );
                if (isDetailedSDKSelectionFoldOut.Value)
                {
                    EditorGUI.BeginChangeCheck();

                    DrawAndHandleSDKSelection <SDK_BaseSystem>("The SDK to use to deal with all system actions.", 1);
                    DrawAndHandleSDKSelection <SDK_BaseBoundaries>("The SDK to use to utilize room scale boundaries.", 1);
                    DrawAndHandleSDKSelection <SDK_BaseHeadset>("The SDK to use to utilize the VR headset.", 1);
                    DrawAndHandleSDKSelection <SDK_BaseController>("The SDK to use to utilize the input devices.", 1);
                    DrawAndHandleSDKSelection <SDK_BaseTracker>("The SDK to use for tracked objects.", 1);
                    DrawAndHandleSDKSelection <SDK_BaseHand>("The SDK to use to utilize the hand-style input devices.", 1);

                    if (EditorGUI.EndChangeCheck())
                    {
                        UpdateDetailedSDKSelectionFoldOut();
                    }
                }

                EditorGUI.indentLevel--;

                string errorDescriptions = string.Join("\n", setup.GetSimplifiedErrorDescriptions());
                if (!string.IsNullOrEmpty(errorDescriptions))
                {
                    EditorGUILayout.HelpBox(errorDescriptions, MessageType.Error);
                }

                if (allAvailableSDKNames.Length != availableSystemSDKNames.Length ||
                    allAvailableSDKNames.Length != availableBoundariesSDKNames.Length ||
                    allAvailableSDKNames.Length != availableHeadsetSDKNames.Length ||
                    allAvailableSDKNames.Length != availableControllerSDKNames.Length ||
                    allAvailableSDKNames.Length != availableTrackerSDKNames.Length ||
                    allAvailableSDKNames.Length != availableHandSDKNames.Length)
                {
                    EditorGUILayout.HelpBox("Only endpoints that are supported by the selected SDK are changed by Quick Select, the others are left untouched."
                                            + "\n\nSome of the available SDK implementations are only available for a subset of SDK endpoints. Quick Select"
                                            + " shows SDKs that provide an implementation for *any* of the different SDK endpoints in VRTK"
                                            + " (System, Boundaries, Headset, Controller, Trackers, Hands).", MessageType.Info);
                }
            }

            using (new EditorGUILayout.VerticalScope("Box"))
            {
                VRTK_EditorUtilities.AddHeader("Object References", false);

                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUI.BeginChangeCheck();
                    bool autoPopulate = EditorGUILayout.Toggle(VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("autoPopulateObjectReferences", "Auto Populate"),
                                                               setup.autoPopulateObjectReferences,
                                                               GUILayout.ExpandWidth(false));
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.FindProperty("autoPopulateObjectReferences").boolValue = autoPopulate;
                        serializedObject.ApplyModifiedProperties();
                        setup.PopulateObjectReferences(false);
                    }

                    const string populateNowDescription = "Populate Now";
                    GUIContent   populateNowGUIContent  = new GUIContent(populateNowDescription, "Set the SDK object references to the objects of the selected SDKs.");
                    if (GUILayout.Button(populateNowGUIContent, GUILayout.MaxHeight(GUI.skin.label.CalcSize(populateNowGUIContent).y)))
                    {
                        Undo.RecordObject(setup, populateNowDescription);
                        setup.PopulateObjectReferences(true);
                    }
                }

                if (setup.autoPopulateObjectReferences)
                {
                    EditorGUILayout.HelpBox("The SDK Setup is configured to automatically populate object references so the following fields are disabled."
                                            + " Uncheck `Auto Populate` above to enable customization of the fields below.", MessageType.Info);
                }

                using (new EditorGUI.DisabledGroupScope(setup.autoPopulateObjectReferences))
                {
                    using (new EditorGUILayout.VerticalScope("Box"))
                    {
                        VRTK_EditorUtilities.AddHeader("Actual Objects", false);
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("actualBoundaries"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("actualBoundaries", "Boundaries")
                            );
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("actualHeadset"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("actualHeadset", "Headset")
                            );
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("actualLeftController"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("actualLeftController", "Left Controller")
                            );
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("actualRightController"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("actualRightController", "Right Controller")
                            );
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("actualTrackers"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("actualTrackers", "Trackers"),
                            true
                            );
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("actualHand"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("actualHand", "Hands")
                            );
                    }

                    using (new EditorGUILayout.VerticalScope("Box"))
                    {
                        VRTK_EditorUtilities.AddHeader("Model Aliases", false);
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("modelAliasLeftController"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("modelAliasLeftController", "Left Controller")
                            );
                        EditorGUILayout.PropertyField(
                            serializedObject.FindProperty("modelAliasRightController"),
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKSetup>("modelAliasRightController", "Right Controller")
                            );
                    }
                }

                EditorGUILayout.HelpBox(
                    "The game object this SDK Setup is attached to will be set inactive automatically to allow for SDK loading and switching.",
                    MessageType.Info
                    );

                IEnumerable <GameObject> referencedObjects = new[]
                {
                    setup.actualBoundaries,
                    setup.actualHeadset,
                    setup.actualLeftController,
                    setup.actualRightController,
                    setup.modelAliasLeftController,
                    setup.modelAliasRightController
                }.Where(referencedObject => referencedObject != null);
                if (referencedObjects.Any(referencedObject => !referencedObject.transform.IsChildOf(setup.transform)))
                {
                    EditorGUILayout.HelpBox(
                        "There is at least one referenced object that is neither a child of, deep child (child of a child) of nor attached to the game object this SDK Setup is attached to.",
                        MessageType.Error
                        );
                }
            }

            serializedObject.ApplyModifiedProperties();
        }
예제 #6
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            VRTK_InteractableObject targ = (VRTK_InteractableObject)target;

            GUILayout.Space(10);
            GUIStyle  guiStyle      = EditorStyles.foldout;
            FontStyle previousStyle = guiStyle.fontStyle;

            guiStyle.fontStyle = FontStyle.Bold;
            viewTouch          = EditorGUILayout.Foldout(viewTouch, "Touch Options", guiStyle);
            guiStyle.fontStyle = previousStyle;
            GUILayout.Space(2);
            if (viewTouch)
            {
                EditorGUI.indentLevel++;

                targ.highlightOnTouch = EditorGUILayout.Toggle(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("highlightOnTouch"), targ.highlightOnTouch);
                if (targ.highlightOnTouch)
                {
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("touchHighlightColor"));
                }

                GUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("rumbleOnTouch"));
                EditorGUI.indentLevel--;
                GUILayout.Label("Strength", GUILayout.MinWidth(49f));
                float y = EditorGUILayout.FloatField(targ.rumbleOnTouch.y, GUILayout.MinWidth(10f));
                GUILayout.Label("Duration", GUILayout.MinWidth(50f));
                float x = EditorGUILayout.FloatField(targ.rumbleOnTouch.x, GUILayout.MinWidth(10f));
                targ.rumbleOnTouch = new Vector2(x, y);
                EditorGUI.indentLevel++;
                GUILayout.EndHorizontal();

                EditorGUILayout.PropertyField(serializedObject.FindProperty("allowedTouchControllers"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("hideControllerOnTouch"));

                EditorGUI.indentLevel--;
            }

            //Grab Layout
            GUILayout.Space(10);
            targ.isGrabbable = EditorGUILayout.Toggle(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("isGrabbable"), targ.isGrabbable);
            if (targ.isGrabbable != isGrabbableLastState && targ.isGrabbable)
            {
                viewGrab = true;
            }
            isGrabbableLastState = targ.isGrabbable;
            if (targ.isGrabbable)
            {
                guiStyle           = EditorStyles.foldout;
                previousStyle      = guiStyle.fontStyle;
                guiStyle.fontStyle = FontStyle.Bold;
                viewGrab           = EditorGUILayout.Foldout(viewGrab, "Grab Options", guiStyle);
                guiStyle.fontStyle = previousStyle;
                GUILayout.Space(2);
                if (viewGrab)
                {
                    EditorGUI.indentLevel++;

                    EditorGUILayout.PropertyField(serializedObject.FindProperty("isDroppable"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("isSwappable"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("holdButtonToGrab"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("grabOverrideButton"));

                    GUILayout.BeginHorizontal();
                    EditorGUILayout.PrefixLabel(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("rumbleOnGrab"));
                    EditorGUI.indentLevel--;
                    GUILayout.Label("Strength", GUILayout.MinWidth(49f));
                    float y = EditorGUILayout.FloatField(targ.rumbleOnGrab.y, GUILayout.MinWidth(10f));
                    GUILayout.Label("Duration", GUILayout.MinWidth(50f));
                    float x = EditorGUILayout.FloatField(targ.rumbleOnGrab.x, GUILayout.MinWidth(10f));
                    targ.rumbleOnGrab = new Vector2(x, y);
                    EditorGUI.indentLevel++;
                    GUILayout.EndHorizontal();

                    EditorGUILayout.PropertyField(serializedObject.FindProperty("allowedGrabControllers"));
                    targ.precisionSnap = EditorGUILayout.Toggle(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("precisionSnap", "Precision Grab(Snap)"), targ.precisionSnap);
                    if (!targ.precisionSnap)
                    {
                        EditorGUILayout.PropertyField(serializedObject.FindProperty("rightSnapHandle"));
                        EditorGUILayout.PropertyField(serializedObject.FindProperty("leftSnapHandle"));
                    }
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("hideControllerOnGrab"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("stayGrabbedOnTeleport"));

                    targ.grabAttachMechanic = (VRTK_InteractableObject.GrabAttachType)EditorGUILayout.EnumPopup(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("grabAttachMechanic"), targ.grabAttachMechanic);
                    if (Array.IndexOf(hasDetachThreshold, targ.grabAttachMechanic) >= 0)
                    {
                        EditorGUILayout.PropertyField(serializedObject.FindProperty("detachThreshold"));
                        if (targ.grabAttachMechanic == VRTK_InteractableObject.GrabAttachType.Spring_Joint)
                        {
                            EditorGUILayout.PropertyField(serializedObject.FindProperty("springJointStrength"));
                            EditorGUILayout.PropertyField(serializedObject.FindProperty("springJointDamper"));
                        }
                    }
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("throwMultiplier"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("onGrabCollisionDelay"));

                    EditorGUI.indentLevel--;
                }
            }

            GUILayout.Space(10);
            targ.isUsable = EditorGUILayout.Toggle(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("isUsable"), targ.isUsable);
            if (targ.isUsable != isUsableLastState && targ.isUsable)
            {
                viewUse = true;
            }

            isUsableLastState = targ.isUsable;
            if (targ.isUsable)
            {
                guiStyle           = EditorStyles.foldout;
                previousStyle      = guiStyle.fontStyle;
                guiStyle.fontStyle = FontStyle.Bold;
                viewUse            = EditorGUILayout.Foldout(viewUse, "Use Options", guiStyle);
                guiStyle.fontStyle = previousStyle;
                GUILayout.Space(2);
                if (viewUse)
                {
                    EditorGUI.indentLevel++;
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("useOnlyIfGrabbed"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("holdButtonToUse"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("useOverrideButton"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("pointerActivatesUseAction"));

                    GUILayout.BeginHorizontal();
                    EditorGUILayout.PrefixLabel(VRTK_EditorUtilities.BuildGUIContent <VRTK_InteractableObject>("rumbleOnUse"));
                    EditorGUI.indentLevel--;
                    GUILayout.Label("Strength", GUILayout.MinWidth(49f));
                    float y = EditorGUILayout.FloatField(targ.rumbleOnUse.y, GUILayout.MinWidth(10f));
                    GUILayout.Label("Duration", GUILayout.MinWidth(50f));
                    float x = EditorGUILayout.FloatField(targ.rumbleOnUse.x, GUILayout.MinWidth(10f));
                    targ.rumbleOnUse = new Vector2(x, y);
                    EditorGUI.indentLevel++;
                    GUILayout.EndHorizontal();

                    EditorGUILayout.PropertyField(serializedObject.FindProperty("allowedUseControllers"));
                    EditorGUILayout.PropertyField(serializedObject.FindProperty("hideControllerOnUse"));

                    EditorGUI.indentLevel--;
                }
            }

            if (targ.GetComponent <VRTK_InteractableObject>().GetType().IsSubclassOf(typeof(VRTK_InteractableObject)))
            {
                GUILayout.Space(10);
                guiStyle           = EditorStyles.foldout;
                previousStyle      = guiStyle.fontStyle;
                guiStyle.fontStyle = FontStyle.Bold;
                viewCustom         = EditorGUILayout.Foldout(viewCustom, "Custom Options", guiStyle);
                guiStyle.fontStyle = previousStyle;
                GUILayout.Space(2);
                if (viewCustom)
                {
                    List <string> excludedProperties = new List <string>();
                    foreach (var ioProperty in typeof(VRTK_InteractableObject).GetFields())
                    {
                        excludedProperties.Add(ioProperty.Name);
                    }

                    DrawPropertiesExcluding(serializedObject, excludedProperties.ToArray());
                }
            }
            serializedObject.ApplyModifiedProperties();
        }
예제 #7
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            var sdkManager = (VRTK_SDKManager)target;

            EditorGUILayout.PropertyField(serializedObject.FindProperty("persistOnLoad"));

            EditorGUILayout.BeginHorizontal();

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(serializedObject.FindProperty("autoPopulateObjectReferences"), GUILayout.ExpandWidth(false));
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
                sdkManager.PopulateObjectReferences(false);
            }

            const string populateNowDescription = "Populate Now";
            var          populateNowGUIContent  = new GUIContent(populateNowDescription, "Set the SDK object references to the objects of the selected SDKs.");

            if (GUILayout.Button(populateNowGUIContent, GUILayout.MaxHeight(GUI.skin.label.CalcSize(populateNowGUIContent).y)))
            {
                Undo.RecordObject(sdkManager, populateNowDescription);
                sdkManager.PopulateObjectReferences(true);
            }

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(serializedObject.FindProperty("autoManageScriptDefines"), GUILayout.ExpandWidth(false));
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
                sdkManager.ManageScriptingDefineSymbols(false, true);
            }

            EditorGUI.BeginDisabledGroup(sdkManager.autoManageScriptDefines);
            const string manageNowDescription = "Manage Now";
            var          manageNowGUIContent  = new GUIContent(
                manageNowDescription,
                "Manage the scripting define symbols defined by the installed SDKs."
                + (sdkManager.autoManageScriptDefines
                   ? "\n\nThis button is disabled because the SDK Manager is set up to manage the scripting define symbols automatically."
                   + " Disable the checkbox on the left to allow managing them manually instead."
                   : "")
                );

            if (GUILayout.Button(manageNowGUIContent, GUILayout.MaxHeight(GUI.skin.label.CalcSize(manageNowGUIContent).y)))
            {
                Undo.RecordObject(sdkManager, manageNowDescription);
                sdkManager.ManageScriptingDefineSymbols(true, true);
            }
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.EndHorizontal();

            var clearSymbolsGUIContent = new GUIContent(
                "Clear All Scripting Define Symbols",
                "Remove all scripting define symbols of VRTK. This is handy if you removed the SDK files from your project but still have"
                + " the symbols defined which results in compile errors."
                + "\nIf you have the above checkbox enabled the symbols will be managed automatically after clearing them. Otherwise hit the"
                + " '" + manageNowDescription + "' button to add the symbols for the currently installed SDKs again."
                );

            if (GUILayout.Button(clearSymbolsGUIContent, VRTK_EditorUtilities.CreateStyle(GUI.skin.button, Color.white, Color.red)))
            {
                //get valid BuildTargetGroups
                BuildTargetGroup[] targetGroups = Enum.GetValues(typeof(BuildTargetGroup)).Cast <BuildTargetGroup>().Where(group =>
                {
                    if (group == BuildTargetGroup.Unknown)
                    {
                        return(false);
                    }

                    string targetGroupName         = Enum.GetName(typeof(BuildTargetGroup), group);
                    FieldInfo targetGroupFieldInfo = typeof(BuildTargetGroup).GetField(targetGroupName, BindingFlags.Public | BindingFlags.Static);

                    return(targetGroupFieldInfo != null && targetGroupFieldInfo.GetCustomAttributes(typeof(ObsoleteAttribute), false).Length == 0);
                }).ToArray();

                foreach (BuildTargetGroup targetGroup in targetGroups)
                {
                    IEnumerable <string> nonSDKSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup)
                                                         .Split(';')
                                                         .Where(symbol => !symbol.StartsWith(SDK_ScriptingDefineSymbolPredicateAttribute.RemovableSymbolPrefix, StringComparison.Ordinal));
                    PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup, string.Join(";", nonSDKSymbols.ToArray()));
                }
            }

            EditorGUILayout.BeginVertical("Box");
            VRTK_EditorUtilities.AddHeader("SDK Selection", false);

            EditorGUILayout.BeginVertical("Box");
            VRTK_EditorUtilities.AddHeader(ObjectNames.NicifyVariableName("activeScriptingDefineSymbolsWithoutSDKClasses"), false);

            Func <VRTK_SDKInfo, string> symbolSelector = info => info.description.symbol;
            var sdkSymbols = new HashSet <string>(
                VRTK_SDKManager.AvailableSystemSDKInfos.Select(symbolSelector)
                .Concat(VRTK_SDKManager.AvailableBoundariesSDKInfos.Select(symbolSelector))
                .Concat(VRTK_SDKManager.AvailableHeadsetSDKInfos.Select(symbolSelector))
                .Concat(VRTK_SDKManager.AvailableControllerSDKInfos.Select(symbolSelector))
                );

            foreach (VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo info in VRTK_SDKManager.AvailableScriptingDefineSymbolPredicateInfos)
            {
                string symbol = info.attribute.symbol;
                if (sdkSymbols.Contains(symbol) ||
                    VRTK_SDKManager.AvailableScriptingDefineSymbolPredicateInfos
                    .Except(new[] { info })
                    .Any(predicateInfo => predicateInfo.methodInfo == info.methodInfo))
                {
                    continue;
                }

                int    index = sdkManager.activeScriptingDefineSymbolsWithoutSDKClasses.FindIndex(attribute => attribute.symbol == symbol);
                string label = symbol.Remove(0, SDK_ScriptingDefineSymbolPredicateAttribute.RemovableSymbolPrefix.Length);

                EditorGUI.BeginChangeCheck();
                bool newValue = EditorGUILayout.ToggleLeft(label, index != -1);
                if (EditorGUI.EndChangeCheck())
                {
                    Undo.RecordObject(sdkManager, "Active Symbol Change");
                    if (newValue)
                    {
                        sdkManager.activeScriptingDefineSymbolsWithoutSDKClasses.Add(info.attribute);
                    }
                    else
                    {
                        sdkManager.activeScriptingDefineSymbolsWithoutSDKClasses.RemoveAt(index);
                    }
                    sdkManager.ManageScriptingDefineSymbols(false, true);
                }
            }

            EditorGUILayout.EndVertical();

            HandleSDKSelection <SDK_BaseSystem>("The SDK to use to deal with all system actions.");
            HandleSDKSelection <SDK_BaseBoundaries>("The SDK to use to utilize room scale boundaries.");
            HandleSDKSelection <SDK_BaseHeadset>("The SDK to use to utilize the VR headset.");
            HandleSDKSelection <SDK_BaseController>("The SDK to use to utilize the input devices.");

            string sdkErrorDescriptions = string.Join("\n", sdkManager.GetSimplifiedSDKErrorDescriptions());

            if (!string.IsNullOrEmpty(sdkErrorDescriptions))
            {
                EditorGUILayout.HelpBox(sdkErrorDescriptions, MessageType.Error);
            }

            EditorGUILayout.Space();

            string[] availableSystemSDKNames     = VRTK_SDKManager.AvailableSystemSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledSystemSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();
            string[] availableBoundariesSDKNames = VRTK_SDKManager.AvailableBoundariesSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledBoundariesSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();
            string[] availableHeadsetSDKNames    = VRTK_SDKManager.AvailableHeadsetSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledHeadsetSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();
            string[] availableControllerSDKNames = VRTK_SDKManager.AvailableControllerSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledControllerSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();

            Func <string, GUIContent> guiContentCreator = sdkName => new GUIContent(sdkName);

            GUIContent[] availableSDKGUIContents = availableSystemSDKNames
                                                   .Intersect(availableBoundariesSDKNames)
                                                   .Intersect(availableHeadsetSDKNames)
                                                   .Intersect(availableControllerSDKNames)
                                                   .Select(guiContentCreator)
                                                   .ToArray();

            EditorGUI.BeginChangeCheck();
            int quicklySelectedSDKIndex = EditorGUILayout.Popup(new GUIContent("Quick select SDK", "Quickly select one of the SDKs into all slots."), 0, availableSDKGUIContents);

            if (EditorGUI.EndChangeCheck())
            {
                string quicklySelectedSDKName       = availableSDKGUIContents[quicklySelectedSDKIndex].text.Replace(SDKNotInstalledDescription, "");
                Func <VRTK_SDKInfo, bool> predicate = info => info.description.prettyName == quicklySelectedSDKName;

                Undo.RecordObject(sdkManager, "SDK Change (Quick Select)");
                sdkManager.systemSDKInfo     = VRTK_SDKManager.AvailableSystemSDKInfos.First(predicate);
                sdkManager.boundariesSDKInfo = VRTK_SDKManager.AvailableBoundariesSDKInfos.First(predicate);
                sdkManager.headsetSDKInfo    = VRTK_SDKManager.AvailableHeadsetSDKInfos.First(predicate);
                sdkManager.controllerSDKInfo = VRTK_SDKManager.AvailableControllerSDKInfos.First(predicate);
            }

            GUIContent[] availableSystemSDKGUIContents     = availableSystemSDKNames.Select(guiContentCreator).ToArray();
            GUIContent[] availableBoundariesSDKGUIContents = availableBoundariesSDKNames.Select(guiContentCreator).ToArray();
            GUIContent[] availableHeadsetSDKGUIContents    = availableHeadsetSDKNames.Select(guiContentCreator).ToArray();
            GUIContent[] availableControllerSDKGUIContents = availableControllerSDKNames.Select(guiContentCreator).ToArray();
            if (availableSDKGUIContents.Length != availableSystemSDKGUIContents.Length ||
                availableSDKGUIContents.Length != availableBoundariesSDKGUIContents.Length ||
                availableSDKGUIContents.Length != availableHeadsetSDKGUIContents.Length ||
                availableSDKGUIContents.Length != availableControllerSDKGUIContents.Length)
            {
                EditorGUILayout.HelpBox("Some of the available SDK implementations are only available for a subset of SDK endpoints. Quick Select only shows SDKs that provide an implementation for *all* the different SDK endpoints in VRTK (System, Boundaries, Headset, Controller).", MessageType.Info);
            }

            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical("Box");
            if (sdkManager.autoPopulateObjectReferences)
            {
                EditorGUILayout.HelpBox("The SDK Manager is configured to auto populate object references so some of the following fields are disabled. Uncheck `Auto Populate Object References` above to enable customization of the below fields.", MessageType.Info);
            }

            VRTK_EditorUtilities.AddHeader("Linked Objects", false);

            EditorGUI.BeginDisabledGroup(sdkManager.autoPopulateObjectReferences);
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualBoundaries"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualHeadset"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualRightController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("modelAliasLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("modelAliasRightController"));
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptAliasLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptAliasRightController"));

            EditorGUILayout.EndVertical();

            serializedObject.ApplyModifiedProperties();
        }
예제 #8
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            VRTK_SDKManager sdkManager = (VRTK_SDKManager)target;

            EditorGUILayout.PropertyField(serializedObject.FindProperty("persistOnLoad"));

            const string manageNowButtonText = "Manage Now";

            using (new EditorGUILayout.VerticalScope("Box"))
            {
                VRTK_EditorUtilities.AddHeader("Scripting Define Symbols", false);

                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUI.BeginChangeCheck();
                    bool autoManage = EditorGUILayout.Toggle(
                        VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("autoManageScriptDefines", "Auto Manage"),
                        sdkManager.autoManageScriptDefines,
                        GUILayout.ExpandWidth(false)
                        );
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.FindProperty("autoManageScriptDefines").boolValue = autoManage;
                        serializedObject.ApplyModifiedProperties();
                        sdkManager.ManageScriptingDefineSymbols(false, true);
                    }

                    using (new EditorGUI.DisabledGroupScope(sdkManager.autoManageScriptDefines))
                    {
                        GUIContent manageNowGUIContent = new GUIContent(
                            manageNowButtonText,
                            "Manage the scripting define symbols defined by the installed SDKs."
                            + (sdkManager.autoManageScriptDefines
                                   ? "\n\nThis button is disabled because the SDK Manager is set up to manage the scripting define symbols automatically."
                               + " Disable the checkbox on the left to allow managing them manually instead."
                                   : "")
                            );
                        if (GUILayout.Button(manageNowGUIContent, GUILayout.MaxHeight(GUI.skin.label.CalcSize(manageNowGUIContent).y)))
                        {
                            sdkManager.ManageScriptingDefineSymbols(true, true);
                        }
                    }
                }

                using (new EditorGUILayout.VerticalScope("Box"))
                {
                    VRTK_EditorUtilities.AddHeader("Active Symbols Without SDK Classes", false);

                    VRTK_SDKInfo[] availableSDKInfos = VRTK_SDKManager
                                                       .AvailableSystemSDKInfos
                                                       .Concat(VRTK_SDKManager.AvailableBoundariesSDKInfos)
                                                       .Concat(VRTK_SDKManager.AvailableHeadsetSDKInfos)
                                                       .Concat(VRTK_SDKManager.AvailableControllerSDKInfos)
                                                       .ToArray();
                    HashSet <string> sdkSymbols = new HashSet <string>(availableSDKInfos.Select(info => info.description.symbol));
                    IGrouping <BuildTargetGroup, VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo>[] availableGroupedPredicateInfos = VRTK_SDKManager
                                                                                                                                        .AvailableScriptingDefineSymbolPredicateInfos
                                                                                                                                        .GroupBy(info => info.attribute.buildTargetGroup)
                                                                                                                                        .ToArray();
                    foreach (IGrouping <BuildTargetGroup, VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo> grouping in availableGroupedPredicateInfos)
                    {
                        VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo[] possibleActiveInfos = grouping
                                                                                                   .Where(info => !sdkSymbols.Contains(info.attribute.symbol) &&
                                                                                                          grouping.Except(new[] { info })
                                                                                                          .All(predicateInfo => !(predicateInfo.methodInfo == info.methodInfo &&
                                                                                                                                  sdkSymbols.Contains(predicateInfo.attribute.symbol))))
                                                                                                   .OrderBy(info => info.attribute.symbol)
                                                                                                   .ToArray();
                        if (possibleActiveInfos.Length == 0)
                        {
                            continue;
                        }

                        EditorGUI.indentLevel++;

                        BuildTargetGroup targetGroup = grouping.Key;
                        isBuildTargetActiveSymbolsFoldOut[targetGroup] = EditorGUI.Foldout(
                            EditorGUILayout.GetControlRect(),
                            isBuildTargetActiveSymbolsFoldOut[targetGroup],
                            targetGroup.ToString(),
                            true
                            );

                        if (isBuildTargetActiveSymbolsFoldOut[targetGroup])
                        {
                            foreach (VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo predicateInfo in possibleActiveInfos)
                            {
                                int symbolIndex = sdkManager
                                                  .activeScriptingDefineSymbolsWithoutSDKClasses
                                                  .FindIndex(attribute => attribute.symbol == predicateInfo.attribute.symbol);
                                string symbolLabel = predicateInfo.attribute.symbol.Remove(
                                    0,
                                    SDK_ScriptingDefineSymbolPredicateAttribute.RemovableSymbolPrefix.Length
                                    );

                                if (!(bool)predicateInfo.methodInfo.Invoke(null, null))
                                {
                                    symbolLabel += " (not installed)";
                                }

                                EditorGUI.BeginChangeCheck();
                                bool isSymbolActive = EditorGUILayout.ToggleLeft(symbolLabel, symbolIndex != -1);
                                if (EditorGUI.EndChangeCheck())
                                {
                                    Undo.RecordObject(sdkManager, "Active Symbol Change");
                                    if (isSymbolActive)
                                    {
                                        sdkManager.activeScriptingDefineSymbolsWithoutSDKClasses.Add(predicateInfo.attribute);
                                    }
                                    else
                                    {
                                        sdkManager.activeScriptingDefineSymbolsWithoutSDKClasses.RemoveAt(symbolIndex);
                                    }
                                    sdkManager.ManageScriptingDefineSymbols(false, true);
                                }
                            }
                        }

                        EditorGUI.indentLevel--;
                    }
                }

                VRTK_EditorUtilities.DrawUsingDestructiveStyle(GUI.skin.button, style =>
                {
                    GUIContent clearSymbolsGUIContent = new GUIContent(
                        "Remove All Symbols",
                        "Remove all scripting define symbols of VRTK. This is handy if you removed the SDK files from your project but still have"
                        + " the symbols defined which results in compile errors."
                        + "\nIf you have the above checkbox enabled the symbols will be managed automatically after clearing them. Otherwise hit the"
                        + " '" + manageNowButtonText + "' button to add the symbols for the currently installed SDKs again."
                        );

                    if (GUILayout.Button(clearSymbolsGUIContent, style))
                    {
                        BuildTargetGroup[] targetGroups = VRTK_SharedMethods.GetValidBuildTargetGroups();

                        foreach (BuildTargetGroup targetGroup in targetGroups)
                        {
                            string[] currentSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup)
                                                      .Split(';')
                                                      .Distinct()
                                                      .OrderBy(symbol => symbol, StringComparer.Ordinal)
                                                      .ToArray();
                            string[] newSymbols = currentSymbols
                                                  .Where(symbol => !symbol.StartsWith(SDK_ScriptingDefineSymbolPredicateAttribute.RemovableSymbolPrefix, StringComparison.Ordinal))
                                                  .ToArray();

                            if (currentSymbols.SequenceEqual(newSymbols))
                            {
                                continue;
                            }

                            PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup, string.Join(";", newSymbols));

                            string[] removedSymbols = currentSymbols.Except(newSymbols).ToArray();
                            if (removedSymbols.Length > 0)
                            {
                                VRTK_Logger.Info(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.SCRIPTING_DEFINE_SYMBOLS_REMOVED, targetGroup, string.Join(", ", removedSymbols)));
                            }
                        }
                    }
                });
            }

            using (new EditorGUILayout.VerticalScope("Box"))
            {
                VRTK_EditorUtilities.AddHeader("Script Aliases", false);
                EditorGUILayout.PropertyField(
                    serializedObject.FindProperty("scriptAliasLeftController"),
                    VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("scriptAliasLeftController", "Left Controller")
                    );
                EditorGUILayout.PropertyField(
                    serializedObject.FindProperty("scriptAliasRightController"),
                    VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("scriptAliasRightController", "Right Controller")
                    );
            }

            using (new EditorGUILayout.VerticalScope("Box"))
            {
                VRTK_EditorUtilities.AddHeader("Setups", false);

                using (new EditorGUILayout.HorizontalScope())
                {
                    EditorGUI.BeginChangeCheck();
                    bool autoManage = EditorGUILayout.Toggle(
                        VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("autoManageVRSettings"),
                        sdkManager.autoManageVRSettings,
                        GUILayout.ExpandWidth(false)
                        );
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.FindProperty("autoManageVRSettings").boolValue = autoManage;
                        serializedObject.ApplyModifiedProperties();
                        sdkManager.ManageVRSettings(false);
                    }

                    using (new EditorGUI.DisabledGroupScope(sdkManager.autoManageVRSettings))
                    {
                        GUIContent manageNowGUIContent = new GUIContent(
                            manageNowButtonText,
                            "Manage the VR settings of the Player Settings to allow for all the installed SDKs."
                            + (sdkManager.autoManageVRSettings
                                   ? "\n\nThis button is disabled because the SDK Manager is set up to manage the VR Settings automatically."
                               + " Disable the checkbox on the left to allow managing them manually instead."
                                   : "")
                            );
                        if (GUILayout.Button(manageNowGUIContent, GUILayout.MaxHeight(GUI.skin.label.CalcSize(manageNowGUIContent).y)))
                        {
                            sdkManager.ManageVRSettings(true);
                        }
                    }
                }

                EditorGUILayout.PropertyField(
                    serializedObject.FindProperty("autoLoadSetup"),
                    VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("autoLoadSetup", "Auto Load")
                    );

                setupsList.DoLayoutList();

                GUIContent autoPopulateGUIContent = new GUIContent("Auto Populate", "Automatically populates the list of SDK Setups with Setups in the scene.");
                if (GUILayout.Button(autoPopulateGUIContent))
                {
                    SerializedProperty serializedProperty = setupsList.serializedProperty;
                    serializedProperty.ClearArray();
                    VRTK_SDKSetup[] setups = sdkManager.GetComponentsInChildren <VRTK_SDKSetup>(true)
                                             .Concat(VRTK_SharedMethods.FindEvenInactiveComponents <VRTK_SDKSetup>())
                                             .Distinct()
                                             .ToArray();

                    for (int index = 0; index < setups.Length; index++)
                    {
                        VRTK_SDKSetup setup = setups[index];
                        serializedProperty.InsertArrayElementAtIndex(index);
                        serializedProperty.GetArrayElementAtIndex(index).objectReferenceValue = setup;
                    }
                }

                if (sdkManager.setups.Length > 1)
                {
                    EditorGUILayout.HelpBox("Duplicated setups are removed automatically.", MessageType.Info);
                }

                if (Enumerable.Range(0, sdkManager.setups.Length).Any(IsSDKSetupNeverUsed))
                {
                    EditorGUILayout.HelpBox("Gray setups will never be loaded because either the SDK Setup isn't valid or there"
                                            + " is a valid Setup before it that uses any non-VR SDK.",
                                            MessageType.Warning);
                }
            }

            using (new EditorGUILayout.VerticalScope("Box"))
            {
                VRTK_EditorUtilities.AddHeader("Target Platform Group Exclusions", false);
                SerializedProperty excludeTargetGroups = serializedObject.FindProperty("excludeTargetGroups");
                excludeTargetGroups.arraySize = EditorGUILayout.IntField("Size", excludeTargetGroups.arraySize);
                for (int i = 0; i < excludeTargetGroups.arraySize; i++)
                {
                    EditorGUILayout.PropertyField(excludeTargetGroups.GetArrayElementAtIndex(i));
                }
            }

            serializedObject.ApplyModifiedProperties();
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            var adaptiveQuality = (VRTK_AdaptiveQuality)target;

            if (adaptiveQuality.GetComponent <SteamVR_Camera>() == null)
            {
                EditorGUILayout.HelpBox(NoSteamVR_CameraFoundHelpBoxText, MessageType.Error);
                return;
            }

            EditorGUILayout.HelpBox(DontDisableHelpBoxText, adaptiveQuality.enabled ? MessageType.Warning : MessageType.Error);
            EditorGUILayout.Space();

            EditorGUILayout.PropertyField(serializedObject.FindProperty("active"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("drawDebugVisualization"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("respondsToKeyboardShortcuts"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("respondsToCommandLineArguments"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("msaaLevel"));

            float minimumRenderScale = adaptiveQuality.minimumRenderScale;
            float maximumRenderScale = adaptiveQuality.maximumRenderScale;

            AddHeader(adaptiveQuality, "minimumRenderScale");
            EditorGUILayout.BeginHorizontal();
            {
                var fieldInfo      = adaptiveQuality.GetType().GetField("minimumRenderScale");
                var rangeAttribute = (RangeAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(RangeAttribute));

                EditorGUI.BeginChangeCheck();
                {
                    float maxFloatWidth = GUI.skin.textField.CalcSize(new GUIContent(1.23f.ToString(CultureInfo.InvariantCulture))).x;
                    minimumRenderScale = EditorGUILayout.FloatField(minimumRenderScale, GUILayout.MaxWidth(maxFloatWidth));

                    EditorGUILayout.MinMaxSlider(
                        ref minimumRenderScale,
                        ref maximumRenderScale,
                        rangeAttribute.min,
                        rangeAttribute.max);

                    maximumRenderScale = EditorGUILayout.FloatField(maximumRenderScale, GUILayout.MaxWidth(maxFloatWidth));
                }
                if (EditorGUI.EndChangeCheck())
                {
                    serializedObject.FindProperty("minimumRenderScale").floatValue =
                        Mathf.Clamp((float)Math.Round(minimumRenderScale, 2), rangeAttribute.min, rangeAttribute.max);
                    serializedObject.FindProperty("maximumRenderScale").floatValue =
                        Mathf.Clamp((float)Math.Round(maximumRenderScale, 2), rangeAttribute.min, rangeAttribute.max);
                }
            }
            EditorGUILayout.EndHorizontal();

            if (maximumRenderScale > adaptiveQuality.BiggestAllowedMaximumRenderScale())
            {
                EditorGUILayout.HelpBox(MaximumRenderScaleTooBigHelpBoxText, MessageType.Error);
            }

            EditorGUILayout.PropertyField(serializedObject.FindProperty("maximumRenderTargetDimension"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("renderScaleFillRateStepSizeInPercent"));

            int  maxRenderScaleLevel = Mathf.Max(adaptiveQuality.renderScales.Count - 1, 0);
            bool disabled            = maxRenderScaleLevel == 0 || !Application.isPlaying;

            EditorGUI.BeginDisabledGroup(disabled);
            {
                AddHeader(adaptiveQuality, "overrideRenderScale");

                if (disabled)
                {
                    EditorGUI.EndDisabledGroup();
                    {
                        EditorGUILayout.HelpBox(NoRenderScaleLevelsYetHelpBoxText, MessageType.Info);
                    }
                    EditorGUI.BeginDisabledGroup(true);
                }

                adaptiveQuality.overrideRenderScale = EditorGUILayout.Toggle(
                    VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("overrideRenderScale"),
                    adaptiveQuality.overrideRenderScale);

                EditorGUI.BeginDisabledGroup(!adaptiveQuality.overrideRenderScale);
                {
                    adaptiveQuality.overrideRenderScaleLevel =
                        EditorGUILayout.IntSlider(
                            VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("overrideRenderScaleLevel"),
                            adaptiveQuality.overrideRenderScaleLevel,
                            0,
                            maxRenderScaleLevel);
                }
                EditorGUI.EndDisabledGroup();
            }
            EditorGUI.EndDisabledGroup();

            serializedObject.ApplyModifiedProperties();
        }
예제 #10
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            //Get actual inspector
            VRTK_SDKManager sdkManager = (VRTK_SDKManager)target;

            EditorGUILayout.BeginVertical("Box");

            EditorGUILayout.PropertyField(serializedObject.FindProperty("persistOnLoad"));

            sdkManager.systemSDK     = (VRTK_SDKManager.SupportedSDKs)EditorGUILayout.EnumPopup(VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("systemSDK"), sdkManager.systemSDK);
            sdkManager.boundariesSDK = (VRTK_SDKManager.SupportedSDKs)EditorGUILayout.EnumPopup(VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("boundariesSDK"), sdkManager.boundariesSDK);
            sdkManager.headsetSDK    = (VRTK_SDKManager.SupportedSDKs)EditorGUILayout.EnumPopup(VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("headsetSDK"), sdkManager.headsetSDK);
            sdkManager.controllerSDK = (VRTK_SDKManager.SupportedSDKs)EditorGUILayout.EnumPopup(VRTK_EditorUtilities.BuildGUIContent <VRTK_SDKManager>("controllerSDK"), sdkManager.controllerSDK);

            CheckSDKUsage(sdkManager.systemSDK, sdkManager.headsetSDK, sdkManager.controllerSDK, sdkManager.boundariesSDK);

            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical("Box");

            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualBoundaries"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualHeadset"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualRightController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("modelAliasLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("modelAliasRightController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptAliasLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptAliasRightController"));

            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical("Box");
            EditorGUILayout.Space();
            if (GUILayout.Button("Auto Populate Linked Objects"))
            {
                AutoPopulate(sdkManager);
            }
            EditorGUILayout.Space();
            EditorGUILayout.EndVertical();

            serializedObject.ApplyModifiedProperties();
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            var sdkManager = (VRTK_SDKManager)target;

            EditorGUILayout.PropertyField(serializedObject.FindProperty("persistOnLoad"));

            EditorGUILayout.BeginHorizontal();

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(serializedObject.FindProperty("autoPopulateObjectReferences"), GUILayout.ExpandWidth(false));
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
                sdkManager.PopulateObjectReferences(false);
            }

            const string populateNowDescription = "Populate Now";
            var          populateNowGUIContent  = new GUIContent(populateNowDescription, "Set the SDK object references to the objects of the selected SDKs.");

            if (GUILayout.Button(populateNowGUIContent, GUILayout.MaxHeight(GUI.skin.label.CalcSize(populateNowGUIContent).y)))
            {
                Undo.RecordObject(sdkManager, populateNowDescription);
                sdkManager.PopulateObjectReferences(true);
            }

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(serializedObject.FindProperty("autoManageScriptDefines"), GUILayout.ExpandWidth(false));
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
                sdkManager.ManageScriptingDefineSymbols(false, false);
            }

            EditorGUI.BeginDisabledGroup(sdkManager.autoManageScriptDefines);
            const string manageNowDescription = "Manage Now";
            var          manageNowGUIContent  = new GUIContent(
                manageNowDescription,
                "Manage the scripting define symbols defined by the selected SDKs."
                + (sdkManager.autoManageScriptDefines
                   ? "\n\nThis button is disabled because the SDK Manager is set up to manage the scripting define symbols automatically."
                   + " Disable the checkbox on the left to allow managing them manually instead."
                   : "")
                );

            if (GUILayout.Button(manageNowGUIContent, GUILayout.MaxHeight(GUI.skin.label.CalcSize(manageNowGUIContent).y)))
            {
                Undo.RecordObject(sdkManager, manageNowDescription);
                sdkManager.ManageScriptingDefineSymbols(true, true);
            }
            EditorGUI.EndDisabledGroup();

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginVertical("Box");
            VRTK_EditorUtilities.AddHeader("SDK Selection", false);

            HandleSDKSelection <SDK_BaseSystem>("The SDK to use to deal with all system actions.");
            HandleSDKSelection <SDK_BaseBoundaries>("The SDK to use to utilize room scale boundaries.");
            HandleSDKSelection <SDK_BaseHeadset>("The SDK to use to utilize the VR headset.");
            HandleSDKSelection <SDK_BaseController>("The SDK to use to utilize the input devices.");

            string sdkErrorDescriptions = string.Join("\n", sdkManager.GetSimplifiedSDKErrorDescriptions());

            if (!string.IsNullOrEmpty(sdkErrorDescriptions))
            {
                EditorGUILayout.HelpBox(sdkErrorDescriptions, MessageType.Error);
            }

            EditorGUILayout.Space();

            string[] availableSystemSDKNames     = VRTK_SDKManager.AvailableSystemSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledSystemSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();
            string[] availableBoundariesSDKNames = VRTK_SDKManager.AvailableBoundariesSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledBoundariesSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();
            string[] availableHeadsetSDKNames    = VRTK_SDKManager.AvailableHeadsetSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledHeadsetSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();
            string[] availableControllerSDKNames = VRTK_SDKManager.AvailableControllerSDKInfos.Select(info => info.description.prettyName + (VRTK_SDKManager.InstalledControllerSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToArray();

            Func <string, GUIContent> guiContentCreator = sdkName => new GUIContent(sdkName);

            GUIContent[] availableSDKGUIContents = availableSystemSDKNames
                                                   .Intersect(availableBoundariesSDKNames)
                                                   .Intersect(availableHeadsetSDKNames)
                                                   .Intersect(availableControllerSDKNames)
                                                   .Select(guiContentCreator)
                                                   .ToArray();

            EditorGUI.BeginChangeCheck();
            int quicklySelectedSDKIndex = EditorGUILayout.Popup(new GUIContent("Quick select SDK", "Quickly select one of the SDKs into all slots."), 0, availableSDKGUIContents);

            if (EditorGUI.EndChangeCheck())
            {
                string quicklySelectedSDKName = availableSDKGUIContents[quicklySelectedSDKIndex].text.Replace(SDKNotInstalledDescription, "");

                Undo.RecordObject(sdkManager, "SDK Change (Quick Select)");
                sdkManager.systemSDKInfo     = VRTK_SDKManager.AvailableSystemSDKInfos.First(info => info.description.prettyName == quicklySelectedSDKName);
                sdkManager.boundariesSDKInfo = VRTK_SDKManager.AvailableBoundariesSDKInfos.First(info => info.description.prettyName == quicklySelectedSDKName);
                sdkManager.headsetSDKInfo    = VRTK_SDKManager.AvailableHeadsetSDKInfos.First(info => info.description.prettyName == quicklySelectedSDKName);
                sdkManager.controllerSDKInfo = VRTK_SDKManager.AvailableControllerSDKInfos.First(info => info.description.prettyName == quicklySelectedSDKName);
            }

            GUIContent[] availableSystemSDKGUIContents     = availableSystemSDKNames.Select(guiContentCreator).ToArray();
            GUIContent[] availableBoundariesSDKGUIContents = availableBoundariesSDKNames.Select(guiContentCreator).ToArray();
            GUIContent[] availableHeadsetSDKGUIContents    = availableHeadsetSDKNames.Select(guiContentCreator).ToArray();
            GUIContent[] availableControllerSDKGUIContents = availableControllerSDKNames.Select(guiContentCreator).ToArray();
            if (availableSDKGUIContents.Length != availableSystemSDKGUIContents.Length ||
                availableSDKGUIContents.Length != availableBoundariesSDKGUIContents.Length ||
                availableSDKGUIContents.Length != availableHeadsetSDKGUIContents.Length ||
                availableSDKGUIContents.Length != availableControllerSDKGUIContents.Length)
            {
                EditorGUILayout.HelpBox("Some of the available SDK implementations are only available for a subset of SDK endpoints. Quick Select only shows SDKs that provide an implementation for *all* the different SDK endpoints in VRTK (System, Boundaries, Headset, Controller).", MessageType.Info);
            }

            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical("Box");
            VRTK_EditorUtilities.AddHeader("Linked Objects", false);

            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualBoundaries"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualHeadset"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("actualRightController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("modelAliasLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("modelAliasRightController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptAliasLeftController"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("scriptAliasRightController"));

            EditorGUILayout.EndVertical();

            serializedObject.ApplyModifiedProperties();
        }
예제 #12
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            VRTK_AdaptiveQuality adaptiveQuality = (VRTK_AdaptiveQuality)target;

            EditorGUILayout.HelpBox(DontDisableHelpBoxText, adaptiveQuality.enabled ? MessageType.Warning : MessageType.Error);
            EditorGUILayout.Space();

            EditorGUILayout.PropertyField(serializedObject.FindProperty("drawDebugVisualization"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("allowKeyboardShortcuts"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("allowCommandLineArguments"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("msaaLevel"));

            EditorGUILayout.Space();
            serializedObject.FindProperty("scaleRenderViewport").boolValue =
                EditorGUILayout.BeginToggleGroup(VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("scaleRenderViewport"),
                                                 adaptiveQuality.scaleRenderViewport);
            {
                Limits2D renderScaleLimits = adaptiveQuality.renderScaleLimits;
                EditorGUILayout.PropertyField(serializedObject.FindProperty("renderScaleLimits"));

                if (renderScaleLimits.maximum > adaptiveQuality.BiggestAllowedMaximumRenderScale())
                {
                    EditorGUILayout.HelpBox(MaximumRenderScaleTooBigHelpBoxText, MessageType.Error);
                }

                EditorGUILayout.PropertyField(serializedObject.FindProperty("maximumRenderTargetDimension"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("renderScaleFillRateStepSizeInPercent"));

                serializedObject.FindProperty("scaleRenderTargetResolution").boolValue =
                    EditorGUILayout.Toggle(VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("scaleRenderTargetResolution"),
                                           adaptiveQuality.scaleRenderTargetResolution);
                if (adaptiveQuality.scaleRenderTargetResolution)
                {
                    EditorGUILayout.HelpBox(ScaleRenderTargetResolutionCostlyHelpBoxText, MessageType.Warning);
                }

                int  maxRenderScaleLevel = Mathf.Max(adaptiveQuality.renderScales.Count - 1, 0);
                bool disabled            = maxRenderScaleLevel == 0 || !Application.isPlaying;

                EditorGUI.BeginDisabledGroup(disabled);
                {
                    VRTK_EditorUtilities.AddHeader <VRTK_AdaptiveQuality>("overrideRenderViewportScale");

                    if (disabled)
                    {
                        EditorGUI.EndDisabledGroup();
                        {
                            EditorGUILayout.HelpBox(NoRenderScaleLevelsYetHelpBoxText, MessageType.Info);
                        }
                        EditorGUI.BeginDisabledGroup(true);
                    }

                    adaptiveQuality.overrideRenderViewportScale = EditorGUILayout.Toggle(
                        VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("overrideRenderViewportScale"),
                        adaptiveQuality.overrideRenderViewportScale);

                    EditorGUI.BeginDisabledGroup(!adaptiveQuality.overrideRenderViewportScale);
                    {
                        adaptiveQuality.overrideRenderViewportScaleLevel =
                            EditorGUILayout.IntSlider(
                                VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("overrideRenderViewportScaleLevel"),
                                adaptiveQuality.overrideRenderViewportScaleLevel,
                                0,
                                maxRenderScaleLevel);
                    }
                    EditorGUI.EndDisabledGroup();
                }
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndToggleGroup();

            if (Application.isPlaying)
            {
                string summary = adaptiveQuality.ToString();
                summary = summary.Substring(summary.IndexOf("\n", StringComparison.Ordinal) + 1);

                VRTK_EditorUtilities.AddHeader("Current State");
                EditorGUILayout.HelpBox(summary, MessageType.None);

                if (GUILayout.RepeatButton("Refresh"))
                {
                    Repaint();
                }
            }

            serializedObject.ApplyModifiedProperties();
        }
예제 #13
0
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            var adaptiveQuality = (VRTK_AdaptiveQuality)target;

            EditorGUILayout.HelpBox(DontDisableHelpBoxText, adaptiveQuality.enabled ? MessageType.Warning : MessageType.Error);
            EditorGUILayout.Space();

            EditorGUILayout.PropertyField(serializedObject.FindProperty("drawDebugVisualization"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("allowKeyboardShortcuts"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("allowCommandLineArguments"));
            EditorGUILayout.PropertyField(serializedObject.FindProperty("msaaLevel"));

            EditorGUILayout.Space();
            serializedObject.FindProperty("scaleRenderViewport").boolValue =
                EditorGUILayout.BeginToggleGroup(VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("scaleRenderViewport"),
                                                 adaptiveQuality.scaleRenderViewport);
            {
                float minimumRenderScale = adaptiveQuality.minimumRenderScale;
                float maximumRenderScale = adaptiveQuality.maximumRenderScale;

                EditorGUILayout.BeginHorizontal();
                {
                    var fieldInfo      = adaptiveQuality.GetType().GetField("minimumRenderScale");
                    var rangeAttribute = (RangeAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(RangeAttribute));

                    EditorGUI.BeginChangeCheck();
                    {
                        float maxFloatWidth = GUI.skin.textField.CalcSize(new GUIContent(1.23f.ToString(CultureInfo.InvariantCulture))).x;
                        minimumRenderScale = EditorGUILayout.FloatField(minimumRenderScale, GUILayout.MaxWidth(maxFloatWidth));

                        EditorGUILayout.MinMaxSlider(
                            ref minimumRenderScale,
                            ref maximumRenderScale,
                            rangeAttribute.min,
                            rangeAttribute.max);

                        maximumRenderScale = EditorGUILayout.FloatField(maximumRenderScale, GUILayout.MaxWidth(maxFloatWidth));
                    }
                    if (EditorGUI.EndChangeCheck())
                    {
                        serializedObject.FindProperty("minimumRenderScale").floatValue =
                            Mathf.Clamp((float)Math.Round(minimumRenderScale, 2), rangeAttribute.min, rangeAttribute.max);
                        serializedObject.FindProperty("maximumRenderScale").floatValue =
                            Mathf.Clamp((float)Math.Round(maximumRenderScale, 2), rangeAttribute.min, rangeAttribute.max);
                    }
                }
                EditorGUILayout.EndHorizontal();

                if (maximumRenderScale > adaptiveQuality.BiggestAllowedMaximumRenderScale())
                {
                    EditorGUILayout.HelpBox(MaximumRenderScaleTooBigHelpBoxText, MessageType.Error);
                }

                EditorGUILayout.PropertyField(serializedObject.FindProperty("maximumRenderTargetDimension"));
                EditorGUILayout.PropertyField(serializedObject.FindProperty("renderScaleFillRateStepSizeInPercent"));

                serializedObject.FindProperty("scaleRenderTargetResolution").boolValue =
                    EditorGUILayout.Toggle(VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("scaleRenderTargetResolution"),
                                           adaptiveQuality.scaleRenderTargetResolution);
                if (adaptiveQuality.scaleRenderTargetResolution)
                {
                    EditorGUILayout.HelpBox(ScaleRenderTargetResolutionCostlyHelpBoxText, MessageType.Warning);
                }

                int  maxRenderScaleLevel = Mathf.Max(adaptiveQuality.renderScales.Count - 1, 0);
                bool disabled            = maxRenderScaleLevel == 0 || !Application.isPlaying;

                EditorGUI.BeginDisabledGroup(disabled);
                {
                    VRTK_EditorUtilities.AddHeader <VRTK_AdaptiveQuality>("overrideRenderViewportScale");

                    if (disabled)
                    {
                        EditorGUI.EndDisabledGroup();
                        {
                            EditorGUILayout.HelpBox(NoRenderScaleLevelsYetHelpBoxText, MessageType.Info);
                        }
                        EditorGUI.BeginDisabledGroup(true);
                    }

                    adaptiveQuality.overrideRenderViewportScale = EditorGUILayout.Toggle(
                        VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("overrideRenderViewportScale"),
                        adaptiveQuality.overrideRenderViewportScale);

                    EditorGUI.BeginDisabledGroup(!adaptiveQuality.overrideRenderViewportScale);
                    {
                        adaptiveQuality.overrideRenderViewportScaleLevel =
                            EditorGUILayout.IntSlider(
                                VRTK_EditorUtilities.BuildGUIContent <VRTK_AdaptiveQuality>("overrideRenderViewportScaleLevel"),
                                adaptiveQuality.overrideRenderViewportScaleLevel,
                                0,
                                maxRenderScaleLevel);
                    }
                    EditorGUI.EndDisabledGroup();
                }
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndToggleGroup();

            if (Application.isPlaying)
            {
                string summary = adaptiveQuality.ToString();
                summary = summary.Substring(summary.IndexOf("\n", StringComparison.Ordinal) + 1);

                VRTK_EditorUtilities.AddHeader("Current State");
                EditorGUILayout.HelpBox(summary, MessageType.None);

                if (GUILayout.RepeatButton("Refresh"))
                {
                    Repaint();
                }
            }

            serializedObject.ApplyModifiedProperties();
        }