|
|
- namespace VRTK
- {
- using UnityEngine;
- using UnityEditor;
- using UnityEditorInternal;
- using System;
- using System.Collections.Generic;
- using System.Linq;
-
- [CustomEditor(typeof(VRTK_SDKManager))]
- public class VRTK_SDKManagerEditor : Editor
- {
- private static readonly Dictionary<BuildTargetGroup, bool> isBuildTargetActiveSymbolsFoldOut;
- private ReorderableList setupsList;
-
- static VRTK_SDKManagerEditor()
- {
- BuildTargetGroup[] targetGroups = VRTK_SharedMethods.GetValidBuildTargetGroups();
- isBuildTargetActiveSymbolsFoldOut = new Dictionary<BuildTargetGroup, bool>(targetGroups.Length);
-
- foreach (BuildTargetGroup targetGroup in targetGroups)
- {
- isBuildTargetActiveSymbolsFoldOut[targetGroup] = true;
- }
- }
-
- 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;
- }
-
- protected virtual void OnDisable()
- {
- Undo.undoRedoPerformed -= UndoRedoPerformed;
- setupsList = null;
- }
-
- public override void OnInspectorGUI()
- {
- serializedObject.Update();
-
- VRTK_SDKManager sdkManager = (VRTK_SDKManager)target;
- 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>(true))
- .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));
- }
- }
-
- EditorGUILayout.PropertyField(serializedObject.FindProperty("persistOnLoad"));
-
- serializedObject.ApplyModifiedProperties();
- }
-
- private void UndoRedoPerformed()
- {
- VRTK_SDKManager sdkManager = (VRTK_SDKManager)target;
- sdkManager.ManageVRSettings(false);
- sdkManager.ManageScriptingDefineSymbols(false, false);
- }
-
- 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;
- }
- }
- }
|