Example #1
0
        // Token: 0x06001B47 RID: 6983 RVA: 0x0008E7CC File Offset: 0x0008C9CC
        public void UnloadSDKSetup(bool disableVR = false)
        {
            if (this.loadedSetup != null)
            {
                this.ToggleBehaviours(false);
            }
            VRTK_SDKSetup loadedSetup = this.loadedSetup;

            this.loadedSetup = null;
            if (loadedSetup != null)
            {
                loadedSetup.OnUnloaded(this);
            }
            if (disableVR)
            {
                XRSettings.LoadDeviceByName("None");
                XRSettings.enabled = false;
            }
            if (loadedSetup != null)
            {
                this.OnLoadedSetupChanged(new VRTK_SDKManager.LoadedSetupChangeEventArgs(loadedSetup, null, null));
            }
            VRTK_SDKManager._previouslyUsedSetupInfos.Clear();
            if (loadedSetup != null)
            {
                VRTK_SDKManager._previouslyUsedSetupInfos.UnionWith(new VRTK_SDKInfo[]
                {
                    loadedSetup.systemSDKInfo,
                    loadedSetup.boundariesSDKInfo,
                    loadedSetup.headsetSDKInfo,
                    loadedSetup.controllerSDKInfo
                });
            }
        }
Example #2
0
        /// <summary>
        /// Unloads the currently loaded <see cref="VRTK_SDKSetup"/>, if there is one.
        /// </summary>
        /// <param name="disableVR">Whether to disable VR altogether after unloading the SDK Setup.</param>
        public void UnloadSDKSetup(bool disableVR = true)
        {
            if (loadedSetup != null)
            {
                ToggleBehaviours(false);
            }

            VRTK_SDKSetup previousLoadedSetup = loadedSetup;

            loadedSetup = null;

            if (previousLoadedSetup != null)
            {
                previousLoadedSetup.OnUnloaded(this);
            }

            if (disableVR)
            {
                UnityEngine.XR.XRSettings.LoadDeviceByName("None");
                UnityEngine.XR.XRSettings.enabled = false;
            }

            if (previousLoadedSetup != null)
            {
                OnLoadedSetupChanged(new LoadedSetupChangeEventArgs(previousLoadedSetup, null, null));
            }
        }
Example #3
0
 /// <summary>
 /// This method is called just before unloading the VRTK_SDKSetup that's using this SDK.
 /// </summary>
 /// <param name="setup">The SDK Setup which is using this SDK.</param>
 public override void OnBeforeSetupUnload(VRTK_SDKSetup setup)
 {
     if (originalSDKRoot != null && GetRootTransform() != null)
     {
         GetRootTransform().parent = originalSDKRoot;
         GetRootTransform().gameObject.SetActive(false);
     }
 }
Example #4
0
        // Token: 0x06001B46 RID: 6982 RVA: 0x0008E558 File Offset: 0x0008C758
        public void TryLoadSDKSetup(int startIndex, bool tryToReinitialize, params VRTK_SDKSetup[] sdkSetups)
        {
            if (sdkSetups.Length == 0)
            {
                return;
            }
            if (startIndex < 0 || startIndex >= sdkSetups.Length)
            {
                VRTK_Logger.Fatal(new ArgumentOutOfRangeException("startIndex"));
                return;
            }
            sdkSetups = sdkSetups.ToList <VRTK_SDKSetup>().GetRange(startIndex, sdkSetups.Length - startIndex).ToArray();
            foreach (VRTK_SDKSetup vrtk_SDKSetup in from setup in sdkSetups
                     where !setup.isValid
                     select setup)
            {
                string text = string.Join("\n- ", vrtk_SDKSetup.GetSimplifiedErrorDescriptions());
                if (!string.IsNullOrEmpty(text))
                {
                    text = "- " + text;
                    VRTK_Logger.Warn(string.Format("Ignoring SDK Setup '{0}' because there are some errors with it:\n{1}", vrtk_SDKSetup.name, text));
                }
            }
            sdkSetups = (from setup in sdkSetups
                         where setup.isValid
                         select setup).ToArray <VRTK_SDKSetup>();
            VRTK_SDKSetup loadedSetup = this.loadedSetup;

            this.ToggleBehaviours(false);
            this.loadedSetup = null;
            if (loadedSetup != null)
            {
                loadedSetup.OnUnloaded(this);
            }
            if (!XRSettings.enabled || !sdkSetups[0].usedVRDeviceNames.Contains(XRSettings.loadedDeviceName))
            {
                if (!tryToReinitialize && !XRSettings.enabled && !string.IsNullOrEmpty(XRSettings.loadedDeviceName))
                {
                    sdkSetups = (from setup in sdkSetups
                                 where !setup.usedVRDeviceNames.Contains(XRSettings.loadedDeviceName)
                                 select setup).ToArray <VRTK_SDKSetup>();
                }
                VRTK_SDKSetup[] array = (from setup in sdkSetups
                                         where setup.usedVRDeviceNames.Except(XRSettings.supportedDevices).Any <string>()
                                         select setup).ToArray <VRTK_SDKSetup>();
                foreach (VRTK_SDKSetup vrtk_SDKSetup2 in array)
                {
                    string arg = string.Join(", ", vrtk_SDKSetup2.usedVRDeviceNames.Except(XRSettings.supportedDevices).ToArray <string>());
                    VRTK_Logger.Warn(string.Format("Ignoring SDK Setup '{0}' because the following VR device names are missing from the PlayerSettings:\n{1}", vrtk_SDKSetup2.name, arg));
                }
                sdkSetups = sdkSetups.Except(array).ToArray <VRTK_SDKSetup>();
                XRSettings.LoadDeviceByName(sdkSetups.SelectMany((VRTK_SDKSetup setup) => setup.usedVRDeviceNames).Distinct <string>().Concat(new string[]
                {
                    "None"
                }).ToArray <string>());
            }
            base.StartCoroutine(this.FinishSDKSetupLoading(sdkSetups, loadedSetup));
        }
Example #5
0
        /// <summary>
        /// Sets a given VRTK_SDKSetup as the loaded SDK Setup to be able to use it when populating object references in the SDK Setup.
        /// This method should only be called when not playing as it's only for populating the object references.
        /// This method is only available in the editor, so usage of the method needs to be surrounded by `#if UNITY_EDITOR` and `#endif` when used
        /// in a type that is also compiled for a standalone build.
        /// </summary>
        /// <param name="setup">The SDK Setup to set as the loaded SDK.</param>
        public void SetLoadedSDKSetupToPopulateObjectReferences(VRTK_SDKSetup setup)
        {
            if (EditorApplication.isPlaying)
            {
                VRTK_Logger.Fatal("The method SetLoadedSDKSetupToPopulateObjectReferences should not be used when the application is playing.");
                return;
            }

            loadedSetup = setup;
        }
Example #6
0
        // Token: 0x06001B6A RID: 7018 RVA: 0x0008F540 File Offset: 0x0008D740
        private static void HandleSDKGetter <BaseType>(string prettyName, VRTK_SDKInfo info, IEnumerable <VRTK_SDKInfo> installedInfos) where BaseType : SDK_Base
        {
            if (VRTK_SharedMethods.IsEditTime())
            {
                return;
            }
            string sdkerrorDescription = VRTK_SDKSetup.GetSDKErrorDescription <BaseType>(prettyName, info, installedInfos);

            if (!string.IsNullOrEmpty(sdkerrorDescription))
            {
                VRTK_Logger.Error(sdkerrorDescription);
            }
        }
        /// <summary>
        /// Draws a popup menu and handles the selection for an SDK info.
        /// </summary>
        /// <typeparam name="BaseType">The SDK base type. Must be a subclass of <see cref="SDK_Base"/>.</typeparam>
        /// <param name="description">The description of the SDK base.</param>
        private void DrawAndHandleSDKSelection <BaseType>(string description, int indentLevelToRemove) where BaseType : SDK_Base
        {
            Type   baseType       = typeof(BaseType);
            Type   sdkManagerType = typeof(VRTK_SDKManager);
            string baseName       = baseType.Name.Remove(0, typeof(SDK_Base).Name.Length);

            ReadOnlyCollection <VRTK_SDKInfo> availableSDKInfos = (ReadOnlyCollection <VRTK_SDKInfo>)sdkManagerType
                                                                  .GetProperty(string.Format("Available{0}SDKInfos", baseName), BindingFlags.Public | BindingFlags.Static)
                                                                  .GetGetMethod()
                                                                  .Invoke(null, null);
            ReadOnlyCollection <VRTK_SDKInfo> installedSDKInfos = (ReadOnlyCollection <VRTK_SDKInfo>)sdkManagerType
                                                                  .GetProperty(string.Format("Installed{0}SDKInfos", baseName), BindingFlags.Public | BindingFlags.Static)
                                                                  .GetGetMethod()
                                                                  .Invoke(null, null);

            PropertyInfo  sdkInfoPropertyInfo = typeof(VRTK_SDKSetup).GetProperty(string.Format("{0}SDKInfo", baseName.ToLowerInvariant()));
            VRTK_SDKSetup sdkSetup            = (VRTK_SDKSetup)target;
            VRTK_SDKInfo  selectedSDKInfo     = (VRTK_SDKInfo)sdkInfoPropertyInfo.GetGetMethod().Invoke(sdkSetup, null);

            List <string> availableSDKNames = availableSDKInfos.Select(info => info.description.prettyName + (installedSDKInfos.Contains(info) ? "" : SDKNotInstalledDescription)).ToList();
            int           selectedSDKIndex  = availableSDKInfos.IndexOf(selectedSDKInfo);

            if (selectedSDKInfo.originalTypeNameWhenFallbackIsUsed != null)
            {
                availableSDKNames.Add(selectedSDKInfo.originalTypeNameWhenFallbackIsUsed + SDKNotFoundAnymoreDescription);
                selectedSDKIndex = availableSDKNames.Count - 1;
            }

            GUIContent[] availableSDKGUIContents = availableSDKNames.Select(availableSDKName => new GUIContent(availableSDKName)).ToArray();

            using (new EditorGUILayout.HorizontalScope())
            {
                EditorGUI.BeginChangeCheck();
                int newSelectedSDKIndex = EditorGUILayout.Popup(
                    new GUIContent(baseName, description),
                    selectedSDKIndex,
                    availableSDKGUIContents
                    );
                VRTK_SDKInfo newSelectedSDKInfo = selectedSDKInfo.originalTypeNameWhenFallbackIsUsed != null &&
                                                  newSelectedSDKIndex == availableSDKNames.Count - 1
                                                      ? selectedSDKInfo
                                                      : availableSDKInfos[newSelectedSDKIndex];
                if (EditorGUI.EndChangeCheck() && newSelectedSDKInfo != selectedSDKInfo)
                {
                    Undo.RecordObject(sdkSetup, string.Format("{0} SDK Change", baseName));
                    sdkInfoPropertyInfo.GetSetMethod().Invoke(sdkSetup, new object[] { newSelectedSDKInfo });
                }

                DrawVRDeviceNameLabel(selectedSDKInfo, baseName, indentLevelToRemove);
            }
        }
Example #8
0
        private bool IsSDKSetupNeverUsed(int sdkSetupIndex)
        {
            VRTK_SDKSetup[] setups = ((VRTK_SDKManager)target).setups;
            VRTK_SDKSetup   setup  = setups[sdkSetupIndex];

            return(setup == null ||
                   !setup.isValid ||
                   Array.FindIndex(
                       setups,
                       0,
                       sdkSetupIndex,
                       sdkSetup => sdkSetup != null &&
                       sdkSetup.isValid &&
                       sdkSetup.usedVRDeviceNames.Contains("None")
                       ) != -1);
        }
Example #9
0
        // Token: 0x06001B4D RID: 6989 RVA: 0x0008E9D3 File Offset: 0x0008CBD3
        private IEnumerator FinishSDKSetupLoading(VRTK_SDKSetup[] sdkSetups, VRTK_SDKSetup previousLoadedSetup)
        {
            yield return(null);

            string loadedDeviceName = string.IsNullOrEmpty(XRSettings.loadedDeviceName) ? "None" : XRSettings.loadedDeviceName;

            this.loadedSetup = sdkSetups.FirstOrDefault((VRTK_SDKSetup setup) => setup.usedVRDeviceNames.Contains(loadedDeviceName));
            if (this.loadedSetup == null)
            {
                this.UnloadSDKSetup(false);
                VRTK_Logger.Error("No SDK Setup from the provided list could be loaded.");
                this.OnLoadedSetupChanged(new VRTK_SDKManager.LoadedSetupChangeEventArgs(previousLoadedSetup, null, "No SDK Setup from the provided list could be loaded."));
                yield break;
            }
            if (this.loadedSetup.usedVRDeviceNames.Except(new string[]
            {
                "None"
            }).Any <string>())
            {
                XRSettings.enabled = true;
                if (!XRDevice.isPresent)
                {
                    int    num  = Array.IndexOf <VRTK_SDKSetup>(sdkSetups, this.loadedSetup) + 1;
                    string text = "An SDK Setup from the provided list could be loaded, but the device is not in working order.";
                    this.ToggleBehaviours(false);
                    this.loadedSetup = null;
                    if (num < sdkSetups.Length && sdkSetups.Length - num > 0)
                    {
                        text += " Now retrying with the remaining SDK Setups from the provided list...";
                        VRTK_Logger.Warn(text);
                        this.OnLoadedSetupChanged(new VRTK_SDKManager.LoadedSetupChangeEventArgs(previousLoadedSetup, null, text));
                        this.TryLoadSDKSetup(num, false, sdkSetups);
                        yield break;
                    }
                    this.UnloadSDKSetup(false);
                    text += " There are no other Setups in the provided list to try.";
                    VRTK_Logger.Error(text);
                    this.OnLoadedSetupChanged(new VRTK_SDKManager.LoadedSetupChangeEventArgs(previousLoadedSetup, null, text));
                    yield break;
                }
            }
            this.loadedSetup.OnLoaded(this);
            this.ToggleBehaviours(true);
            this.OnLoadedSetupChanged(new VRTK_SDKManager.LoadedSetupChangeEventArgs(previousLoadedSetup, this.loadedSetup, null));
            yield break;
        }
        protected virtual void AddSelectionButtons()
        {
            VRTK_SDKSetup loadedSetup = sdkManager.loadedSetup;

            if (loadedSetup != null)
            {
                GameObject chooseNoneButton = Instantiate(chooseButton.gameObject, chooseButton.transform.parent);
                chooseNoneButton.GetComponentInChildren <Text>().text = "None";
                chooseNoneButton.name = "ChooseNoneButton";
                chooseNoneButton.SetActive(true);

                chooseNoneButton.GetComponent <Button>().onClick.AddListener(
                    () => sdkManager.UnloadSDKSetup(true)
                    );

                chooseButtonGameObjects.Add(chooseNoneButton);
            }

            VRTK_SDKSetup[] setups = sdkManager.setups;
            for (int index = 0; index < setups.Length; index++)
            {
                VRTK_SDKSetup setup = setups[index];
                if (setup == null || setup == loadedSetup)
                {
                    continue;
                }

                GameObject chooseButtonCopy = Instantiate(chooseButton.gameObject, chooseButton.transform.parent);
                chooseButtonCopy.GetComponentInChildren <Text>().text = setup.name;
                chooseButtonCopy.name = string.Format("Choose{0}Button", setup.name);
                chooseButtonCopy.SetActive(true);

                int    indexCopy = index;
                Button button    = chooseButtonCopy.GetComponent <Button>();
                button.onClick.AddListener(
                    () => sdkManager.TryLoadSDKSetup(indexCopy, true, setups)
                    );

                ColorBlock buttonColors = button.colors;
                buttonColors.colorMultiplier = setup.isValid ? 1.0f : 0.8f;
                button.colors = buttonColors;

                chooseButtonGameObjects.Add(chooseButtonCopy);
            }
        }
Example #11
0
        /// <summary>
        /// Unloads the currently loaded <see cref="VRTK_SDKSetup"/>, if there is one.
        /// </summary>
        /// <param name="disableVR">Whether to disable VR altogether after unloading the SDK Setup.</param>
        public void UnloadSDKSetup(bool disableVR = false)
        {
            if (loadedSetup != null)
            {
                ToggleBehaviours(false);
            }

            VRTK_SDKSetup previousLoadedSetup = loadedSetup;

            loadedSetup = null;

            if (previousLoadedSetup != null)
            {
                previousLoadedSetup.OnUnloaded(this);
            }

            if (disableVR)
            {
                VRSettings.LoadDeviceByName("None");
                VRSettings.enabled = false;
            }

            if (previousLoadedSetup != null)
            {
                OnLoadedSetupChanged(new LoadedSetupChangeEventArgs(previousLoadedSetup, null, null));
            }

            _previouslyUsedSetupInfos.Clear();
            if (previousLoadedSetup != null)
            {
                _previouslyUsedSetupInfos.UnionWith(
                    new[]
                {
                    previousLoadedSetup.systemSDKInfo,
                    previousLoadedSetup.boundariesSDKInfo,
                    previousLoadedSetup.headsetSDKInfo,
                    previousLoadedSetup.controllerSDKInfo
                }
                    );
            }
        }
Example #12
0
        private bool AreAllSDKsTheSame()
        {
            VRTK_SDKSetup setup = (VRTK_SDKSetup)target;

            VRTK_SDKInfo[] infos =
            {
                setup.systemSDKInfo,
                setup.boundariesSDKInfo,
                setup.headsetSDKInfo,
                setup.controllerSDKInfo,
            };

            if (infos.Any(info => info.originalTypeNameWhenFallbackIsUsed != null))
            {
                return(false);
            }

            return(infos.Select(info => info.description.prettyName)
                   .Distinct()
                   .Count() == 1);
        }
Example #13
0
        // Token: 0x06001B7B RID: 7035 RVA: 0x0008F99C File Offset: 0x0008DB9C
        protected virtual void AddSelectionButtons()
        {
            VRTK_SDKSetup loadedSetup = this.sdkManager.loadedSetup;

            if (loadedSetup != null)
            {
                GameObject gameObject = Object.Instantiate <GameObject>(this.chooseButton.gameObject, this.chooseButton.transform.parent);
                gameObject.GetComponentInChildren <Text>().text = "None";
                gameObject.name = "ChooseNoneButton";
                gameObject.SetActive(true);
                gameObject.GetComponent <Button>().onClick.AddListener(delegate()
                {
                    this.sdkManager.UnloadSDKSetup(true);
                });
                this.chooseButtonGameObjects.Add(gameObject);
            }
            VRTK_SDKSetup[] setups = this.sdkManager.setups;
            for (int i = 0; i < setups.Length; i++)
            {
                VRTK_SDKSetup vrtk_SDKSetup = setups[i];
                if (!(vrtk_SDKSetup == null) && !(vrtk_SDKSetup == loadedSetup))
                {
                    GameObject gameObject2 = Object.Instantiate <GameObject>(this.chooseButton.gameObject, this.chooseButton.transform.parent);
                    gameObject2.GetComponentInChildren <Text>().text = vrtk_SDKSetup.name;
                    gameObject2.name = string.Format("Choose{0}Button", vrtk_SDKSetup.name);
                    gameObject2.SetActive(true);
                    int    indexCopy = i;
                    Button component = gameObject2.GetComponent <Button>();
                    component.onClick.AddListener(delegate()
                    {
                        this.sdkManager.TryLoadSDKSetup(indexCopy, true, setups);
                    });
                    ColorBlock colors = component.colors;
                    colors.colorMultiplier = (vrtk_SDKSetup.isValid ? 1f : 0.8f);
                    component.colors       = colors;
                    this.chooseButtonGameObjects.Add(gameObject2);
                }
            }
        }
        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();
        }
        protected virtual void UpdateCurrentText()
        {
            VRTK_SDKSetup loadedSetup = VRTK_SDKManager.GetLoadedSDKSetup();

            currentText.text = (loadedSetup == null ? "None" : loadedSetup.name);
        }
Example #16
0
        protected virtual void OnEnable()
        {
            VRTK_SDKManager sdkManager = (VRTK_SDKManager)target;

            setupsList = new ReorderableList(serializedObject, serializedObject.FindProperty("setups"))
            {
                headerHeight        = 2,
                drawElementCallback = (rect, index, active, focused) =>
                {
                    SerializedProperty serializedProperty = setupsList.serializedProperty;
                    if (serializedProperty.arraySize <= index)
                    {
                        return;
                    }

                    rect.y     += 2;
                    rect.height = EditorGUIUtility.singleLineHeight;

                    Color previousColor = GUI.color;
                    if (IsSDKSetupNeverUsed(index))
                    {
                        GUI.color = new Color(previousColor.r, previousColor.g, previousColor.b, 0.5f);
                    }

                    GUIContent unloadButtonGUIContent = new GUIContent("Unload", "Unload this SDK Setup.");
                    GUIContent loadButtonGUIContent   = new GUIContent("Load", "Try to load this SDK Setup.");
                    float      buttonGUIContentWidth  = Mathf.Max(
                        GUI.skin.button.CalcSize(unloadButtonGUIContent).x,
                        GUI.skin.button.CalcSize(loadButtonGUIContent).x
                        );

                    VRTK_SDKSetup setup = (VRTK_SDKSetup)serializedProperty.GetArrayElementAtIndex(index).objectReferenceValue;
                    if (EditorApplication.isPlaying && setup != null)
                    {
                        rect.width -= buttonGUIContentWidth + ReorderableList.Defaults.padding;
                    }

                    EditorGUI.BeginChangeCheck();
                    EditorGUI.PropertyField(rect,
                                            serializedProperty.GetArrayElementAtIndex(index),
                                            GUIContent.none);
                    if (EditorGUI.EndChangeCheck())
                    {
                        setup = (VRTK_SDKSetup)serializedProperty.GetArrayElementAtIndex(index).objectReferenceValue;
                        if (setup != null)
                        {
                            int indexOfExistingDuplicateSetup = Enumerable
                                                                .Range(0, serializedProperty.arraySize)
                                                                .Except(new[] { index })
                                                                .Where(i => (VRTK_SDKSetup)serializedProperty.GetArrayElementAtIndex(i).objectReferenceValue == setup)
                                                                .DefaultIfEmpty(-1)
                                                                .First();
                            if (indexOfExistingDuplicateSetup != -1)
                            {
                                serializedProperty.GetArrayElementAtIndex(indexOfExistingDuplicateSetup).objectReferenceValue = null;

                                setupsList.index = indexOfExistingDuplicateSetup;
                                ReorderableList.defaultBehaviours.DoRemoveButton(setupsList);
                                setupsList.index = index;
                            }
                        }
                        sdkManager.ManageVRSettings(false);
                    }

                    GUI.color = previousColor;

                    if (EditorApplication.isPlaying && setup != null)
                    {
                        rect.x    += rect.width + ReorderableList.Defaults.padding;
                        rect.width = buttonGUIContentWidth;

                        if (sdkManager.loadedSetup == setup)
                        {
                            if (GUI.Button(rect, unloadButtonGUIContent))
                            {
                                sdkManager.UnloadSDKSetup();
                            }
                        }
                        else
                        {
                            if (GUI.Button(rect, loadButtonGUIContent))
                            {
                                sdkManager.TryLoadSDKSetup(index, true, sdkManager.setups);
                            }
                        }
                    }
                },
                onAddCallback = list =>
                {
                    SerializedProperty serializedProperty = list.serializedProperty;
                    int index = serializedProperty.arraySize;
                    serializedProperty.arraySize++;
                    list.index = index;

                    SerializedProperty element = serializedProperty.GetArrayElementAtIndex(index);
                    element.objectReferenceValue = null;

                    sdkManager.ManageVRSettings(false);
                },
                onRemoveCallback = list =>
                {
                    int           index    = list.index;
                    VRTK_SDKSetup sdkSetup = sdkManager.setups[index];
                    bool          isLoaded = sdkManager.loadedSetup == sdkSetup;

                    if (isLoaded)
                    {
                        sdkManager.UnloadSDKSetup();
                    }

                    if (sdkSetup != null)
                    {
                        list.serializedProperty.GetArrayElementAtIndex(index).objectReferenceValue = null;
                    }

                    ReorderableList.defaultBehaviours.DoRemoveButton(list);
                    sdkManager.ManageVRSettings(false);
                },
                onReorderCallback = list => sdkManager.ManageVRSettings(false)
            };

            Undo.undoRedoPerformed += UndoRedoPerformed;
        }
Example #17
0
 /// <summary>
 /// This method is called just before loading the VRTK_SDKSetup that's using this SDK.
 /// </summary>
 /// <param name="setup">The SDK Setup which is using this SDK.</param>
 public override void OnBeforeSetupLoad(VRTK_SDKSetup setup)
 {
     originalSDKRoot = GetRootTransform() != null?GetRootTransform().parent : null;
 }
Example #18
0
 public LoadedSetupChangeEventArgs(VRTK_SDKSetup previousSetup, VRTK_SDKSetup currentSetup, string errorMessage)
 {
     this.previousSetup = previousSetup;
     this.currentSetup  = currentSetup;
     this.errorMessage  = errorMessage;
 }
Example #19
0
 /// <summary>
 /// This method is called just before unloading the <see cref="VRTK_SDKSetup"/> that's using this SDK.
 /// </summary>
 /// <param name="setup">The SDK Setup which is using this SDK.</param>
 public virtual void OnBeforeSetupUnload(VRTK_SDKSetup setup)
 {
 }
Example #20
0
        }                                                                                                                                                             // 0x0000000180246DB0-0x0000000180246DC0

        public virtual void u0924u091Eu0929u0920u091Du091Eu0923u091Bu0921u0929u0924(VRTK_SDKSetup u0924u091Au091Eu091Fu0927u0923u0927u0925u0924u0928u0921)
        {
        }                                                                                                                                                             // 0x0000000180246DB0-0x0000000180246DC0
        protected virtual void UpdateCurrentText()
        {
            VRTK_SDKSetup loadedSetup = sdkManager.loadedSetup;

            currentText.text = loadedSetup == null ? "None" : loadedSetup.name;
        }
Example #22
0
        /// <summary>
        /// Tries to load a valid VRTK_SDKSetup from a list.
        /// </summary>
        /// <remarks>
        /// The first loadable VRTK_SDKSetup in the list will be loaded. Will fall back to disable VR if none of the provided Setups is useable.
        /// </remarks>
        /// <param name="startIndex">The index of the VRTK_SDKSetup to start the loading with.</param>
        /// <param name="tryToReinitialize">Whether or not to retry initializing and using the currently set but unusable VR Device.</param>
        /// <param name="sdkSetups">The list to try to load a VRTK_SDKSetup from.</param>
        public void TryLoadSDKSetup(int startIndex, bool tryToReinitialize, params VRTK_SDKSetup[] sdkSetups)
        {
            if (sdkSetups.Length == 0)
            {
                return;
            }

            if (startIndex < 0 || startIndex >= sdkSetups.Length)
            {
                VRTK_Logger.Fatal(new ArgumentOutOfRangeException("startIndex"));
                return;
            }

            sdkSetups = sdkSetups.ToList()
                        .GetRange(startIndex, sdkSetups.Length - startIndex)
                        .ToArray();

            foreach (VRTK_SDKSetup invalidSetup in sdkSetups.Where(setup => !setup.isValid))
            {
                string setupErrorDescriptions = string.Join("\n- ", invalidSetup.GetSimplifiedErrorDescriptions());
                if (!string.IsNullOrEmpty(setupErrorDescriptions))
                {
                    setupErrorDescriptions = "- " + setupErrorDescriptions;
                    VRTK_Logger.Warn(string.Format("Ignoring SDK Setup '{0}' because there are some errors with it:\n{1}", invalidSetup.name, setupErrorDescriptions));
                }
            }

            sdkSetups = sdkSetups.Where(setup => setup.isValid).ToArray();

            VRTK_SDKSetup previousLoadedSetup = loadedSetup;

            ToggleBehaviours(false);
            loadedSetup = null;
            if (previousLoadedSetup != null)
            {
                previousLoadedSetup.OnUnloaded(this);
            }

            string loadedDeviceName      = string.IsNullOrEmpty(XRSettings.loadedDeviceName) ? "None" : XRSettings.loadedDeviceName;
            bool   isDeviceAlreadyLoaded = sdkSetups[0].usedVRDeviceNames.Contains(loadedDeviceName);

            if (!isDeviceAlreadyLoaded)
            {
                if (!tryToReinitialize && !XRSettings.enabled && loadedDeviceName != "None")
                {
                    sdkSetups = sdkSetups.Where(setup => !setup.usedVRDeviceNames.Contains(loadedDeviceName))
                                .ToArray();
                }

                VRTK_SDKSetup[] missingVRDeviceSetups = sdkSetups
                                                        .Where(setup => setup.usedVRDeviceNames.Except(XRSettings.supportedDevices.Concat(new[] { "None" })).Any())
                                                        .ToArray();
                foreach (VRTK_SDKSetup missingVRDeviceSetup in missingVRDeviceSetups)
                {
                    string missingVRDevicesText = string.Join(
                        ", ",
                        missingVRDeviceSetup.usedVRDeviceNames
                        .Except(XRSettings.supportedDevices)
                        .ToArray()
                        );
                    VRTK_Logger.Warn(string.Format("Ignoring SDK Setup '{0}' because the following VR device names are missing from the PlayerSettings:\n{1}",
                                                   missingVRDeviceSetup.name,
                                                   missingVRDevicesText));
                }

                sdkSetups = sdkSetups.Except(missingVRDeviceSetups).ToArray();
                string[] vrDeviceNames = sdkSetups
                                         .SelectMany(setup => setup.usedVRDeviceNames)
                                         .Distinct()
                                         .Concat(new[] { "None" }) // Add "None" to the end to fall back to
                                         .ToArray();
                XRSettings.LoadDeviceByName(vrDeviceNames);
            }

            StartCoroutine(FinishSDKSetupLoading(sdkSetups, previousLoadedSetup));
        }
Example #23
0
 /// <summary>
 /// This method is called just after unloading the <see cref="VRTK_SDKSetup"/> that's using this SDK.
 /// </summary>
 /// <param name="setup">The SDK Setup which is using this SDK.</param>
 public virtual void OnAfterSetupUnload(VRTK_SDKSetup setup)
 {
 }
Example #24
0
        // Token: 0x06001B7A RID: 7034 RVA: 0x0008F960 File Offset: 0x0008DB60
        protected virtual void UpdateCurrentText()
        {
            VRTK_SDKSetup loadedSetup = this.sdkManager.loadedSetup;

            this.currentText.text = ((loadedSetup == null) ? "None" : loadedSetup.name);
        }
Example #25
0
        private IEnumerator FinishSDKSetupLoading(VRTK_SDKSetup[] sdkSetups, VRTK_SDKSetup previousLoadedSetup)
        {
            yield return(null);

            string loadedDeviceName = string.IsNullOrEmpty(XRSettings.loadedDeviceName) ? "None" : XRSettings.loadedDeviceName;

            loadedSetup = sdkSetups.FirstOrDefault(setup => setup.usedVRDeviceNames.Contains(loadedDeviceName));

            if (loadedSetup == null)
            {
                // The loaded VR Device doesn't match any SDK Setup
                UnloadSDKSetup();

                const string errorMessage = "No SDK Setup from the provided list could be loaded.";
                OnLoadedSetupChanged(new LoadedSetupChangeEventArgs(previousLoadedSetup, null, errorMessage));
                VRTK_Logger.Error(errorMessage);

                yield break;
            }

            if (loadedSetup.usedVRDeviceNames.Except(new[] { "None" }).Any())
            {
                // The loaded VR Device is actually a VR Device
                XRSettings.enabled = true;

                if (!XRDevice.isPresent)
                {
                    // Despite being loaded, the loaded VR Device isn't working correctly
                    int    nextSetupIndex = Array.IndexOf(sdkSetups, loadedSetup) + 1;
                    string errorMessage   = "An SDK Setup from the provided list could be loaded, but the device is not in working order.";

                    ToggleBehaviours(false);
                    loadedSetup = null;

                    if (nextSetupIndex < sdkSetups.Length && sdkSetups.Length - nextSetupIndex > 0)
                    {
                        // Let's try loading the remaining SDK Setups
                        errorMessage += " Now retrying with the remaining SDK Setups from the provided list...";
                        VRTK_Logger.Warn(errorMessage);
                        OnLoadedSetupChanged(new LoadedSetupChangeEventArgs(previousLoadedSetup, null, errorMessage));

                        TryLoadSDKSetup(nextSetupIndex, false, sdkSetups);
                        yield break;
                    }

                    // There are no other SDK Setups
                    UnloadSDKSetup();

                    errorMessage += " There are no other Setups in the provided list to try.";
                    OnLoadedSetupChanged(new LoadedSetupChangeEventArgs(previousLoadedSetup, null, errorMessage));
                    VRTK_Logger.Error(errorMessage);

                    yield break;
                }
            }

            // A VR Device was correctly loaded, is working and matches an SDK Setup
            loadedSetup.OnLoaded(this);
            ToggleBehaviours(true);
            CheckControllersReady();
            OnLoadedSetupChanged(new LoadedSetupChangeEventArgs(previousLoadedSetup, loadedSetup, null));
        }
Example #26
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();
        }