// Token: 0x06001B4F RID: 6991 RVA: 0x0008EA94 File Offset: 0x0008CC94 private static void PopulateAvailableScriptingDefineSymbolPredicateInfos() { List <VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo> list = new List <VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo>(); foreach (Type type in typeof(VRTK_SDKManager).Assembly.GetTypes()) { for (int j = 0; j < type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Length; j++) { MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)[j]; SDK_ScriptingDefineSymbolPredicateAttribute[] array = (SDK_ScriptingDefineSymbolPredicateAttribute[])methodInfo.GetCustomAttributes(typeof(SDK_ScriptingDefineSymbolPredicateAttribute), false); if (array.Length != 0) { if (methodInfo.ReturnType != typeof(bool) || methodInfo.GetParameters().Length != 0) { VRTK_Logger.Fatal(new InvalidOperationException(string.Format("The method '{0}' on '{1}' has '{2}' specified but its signature is wrong. The method must take no arguments and return bool.", methodInfo.Name, type, typeof(SDK_ScriptingDefineSymbolPredicateAttribute)))); return; } list.AddRange(from predicateAttribute in array select new VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo(predicateAttribute, methodInfo)); } } } list.Sort((VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo x, VRTK_SDKManager.ScriptingDefineSymbolPredicateInfo y) => string.Compare(x.attribute.symbol, y.attribute.symbol, StringComparison.Ordinal)); VRTK_SDKManager.AvailableScriptingDefineSymbolPredicateInfos = list.AsReadOnly(); }
/// <summary> /// Populates `AvailableScriptingDefineSymbolPredicateInfos` with all the available SDK_ScriptingDefineSymbolPredicateAttributes and associated method infos. /// </summary> private static void PopulateAvailableScriptingDefineSymbolPredicateInfos() { List <ScriptingDefineSymbolPredicateInfo> predicateInfos = new List <ScriptingDefineSymbolPredicateInfo>(); foreach (Type type in typeof(VRTK_SDKManager).Assembly.GetTypes()) { for (int index = 0; index < type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static).Length; index++) { MethodInfo methodInfo = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)[index]; SDK_ScriptingDefineSymbolPredicateAttribute[] predicateAttributes = (SDK_ScriptingDefineSymbolPredicateAttribute[])methodInfo.GetCustomAttributes(typeof(SDK_ScriptingDefineSymbolPredicateAttribute), false); if (predicateAttributes.Length == 0) { continue; } if (methodInfo.ReturnType != typeof(bool) || methodInfo.GetParameters().Length != 0) { VRTK_Logger.Fatal(new InvalidOperationException(string.Format("The method '{0}' on '{1}' has '{2}' specified but its signature is wrong. The method must take no arguments and return bool.", methodInfo.Name, type, typeof(SDK_ScriptingDefineSymbolPredicateAttribute)))); return; } predicateInfos.AddRange(predicateAttributes.Select(predicateAttribute => new ScriptingDefineSymbolPredicateInfo(predicateAttribute, methodInfo))); } } predicateInfos.Sort((x, y) => string.Compare(x.attribute.symbol, y.attribute.symbol, StringComparison.Ordinal)); AvailableScriptingDefineSymbolPredicateInfos = predicateInfos.AsReadOnly(); }
protected virtual void Show(ViewingState viewingState) { switch (viewingState) { case ViewingState.Status: RemoveCreatedChooseButtons(); UpdateCurrentText(); selectionPanel.gameObject.SetActive(false); statusPanel.gameObject.SetActive(true); break; case ViewingState.Selection: AddSelectionButtons(); selectionPanel.gameObject.SetActive(true); statusPanel.gameObject.SetActive(false); break; default: VRTK_Logger.Fatal(new ArgumentOutOfRangeException("viewingState", viewingState, null)); return; } fallbackCamera.gameObject.SetActive(Camera.main == null || Camera.main == fallbackCamera); eventSystem.gameObject.SetActive(EventSystem.current == null || EventSystem.current == eventSystem); }
/// <summary> /// Creates a new attribute. /// </summary> /// <param name="symbol">The scripting define symbol to conditionally add or remove. Needs to start with <see cref="RemovableSymbolPrefix"/> to be able to automatically remove the symbol. <see langword="null"/> and <see cref="string.Empty"/> aren't allowed.</param> /// <param name="buildTargetGroupName">The name of a constant of <see cref="BuildTargetGroup"/>. <see cref="BuildTargetGroup.Unknown"/>, <see langword="null"/> and <see cref="string.Empty"/> aren't allowed.</param> public SDK_ScriptingDefineSymbolPredicateAttribute(string symbol, string buildTargetGroupName) { if (symbol == null) { VRTK_Logger.Fatal(new ArgumentNullException("symbol")); return; } if (symbol == string.Empty) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("symbol", symbol, "An empty string isn't allowed.")); return; } this.symbol = symbol; if (buildTargetGroupName == null) { VRTK_Logger.Fatal(new ArgumentNullException("buildTargetGroupName")); return; } if (buildTargetGroupName == string.Empty) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("buildTargetGroupName", buildTargetGroupName, "An empty string isn't allowed.")); return; } SetBuildTarget(buildTargetGroupName); }
/// <summary> /// Creates a new attribute by copying from another attribute on a given type. /// </summary> /// <param name="typeToCopyExistingDescriptionFrom">The type to copy the existing SDK_DescriptionAttribute from. `null` is not allowed.</param> /// <param name="index">The index of the description to copy from the the existing SDK_DescriptionAttribute.</param> public SDK_DescriptionAttribute(Type typeToCopyExistingDescriptionFrom, int index = 0) { if (typeToCopyExistingDescriptionFrom == null) { VRTK_Logger.Fatal(new ArgumentNullException("typeToCopyExistingDescriptionFrom")); return; } Type descriptionType = typeof(SDK_DescriptionAttribute); SDK_DescriptionAttribute[] descriptions = GetDescriptions(typeToCopyExistingDescriptionFrom); if (descriptions.Length == 0) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("typeToCopyExistingDescriptionFrom", typeToCopyExistingDescriptionFrom, string.Format("'{0}' doesn't specify any SDK descriptions via '{1}' to copy.", typeToCopyExistingDescriptionFrom.Name, descriptionType.Name))); return; } if (descriptions.Length <= index) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("index", index, string.Format("'{0}' has no '{1}' at that index.", typeToCopyExistingDescriptionFrom.Name, descriptionType.Name))); return; } SDK_DescriptionAttribute description = descriptions[index]; prettyName = description.prettyName; symbol = description.symbol; vrDeviceName = description.vrDeviceName; this.index = index; #if UNITY_EDITOR buildTargetGroup = description.buildTargetGroup; #endif }
// Token: 0x06001277 RID: 4727 RVA: 0x00069290 File Offset: 0x00067490 public SDK_DescriptionAttribute(Type typeToCopyExistingDescriptionFrom, int index = 0) { if (typeToCopyExistingDescriptionFrom == null) { VRTK_Logger.Fatal(new ArgumentNullException("typeToCopyExistingDescriptionFrom")); return; } Type typeFromHandle = typeof(SDK_DescriptionAttribute); SDK_DescriptionAttribute[] descriptions = SDK_DescriptionAttribute.GetDescriptions(typeToCopyExistingDescriptionFrom); if (descriptions.Length == 0) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("typeToCopyExistingDescriptionFrom", typeToCopyExistingDescriptionFrom, string.Format("'{0}' doesn't specify any SDK descriptions via '{1}' to copy.", typeToCopyExistingDescriptionFrom.Name, typeFromHandle.Name))); return; } if (descriptions.Length <= index) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("index", index, string.Format("'{0}' has no '{1}' at that index.", typeToCopyExistingDescriptionFrom.Name, typeFromHandle.Name))); return; } SDK_DescriptionAttribute sdk_DescriptionAttribute = descriptions[index]; this.prettyName = sdk_DescriptionAttribute.prettyName; this.symbol = sdk_DescriptionAttribute.symbol; this.vrDeviceName = sdk_DescriptionAttribute.vrDeviceName; this.index = index; }
protected virtual void Show(ViewingState viewingState) { switch (viewingState) { case ViewingState.Status: RemoveCreatedChooseButtons(); UpdateCurrentText(); selectionPanel.gameObject.SetActive(false); statusPanel.gameObject.SetActive(true); break; case ViewingState.Selection: AddSelectionButtons(); selectionPanel.gameObject.SetActive(true); statusPanel.gameObject.SetActive(false); break; default: VRTK_Logger.Fatal(new ArgumentOutOfRangeException("viewingState", viewingState, null)); return; } bool isAnyOtherCameraUsed = VRTK_SDKManager.GetAllSDKSetups().Any(setup => setup != null && setup.gameObject.activeSelf) || VRTK_DeviceFinder.HeadsetCamera() != null; fallbackCamera.gameObject.SetActive(!isAnyOtherCameraUsed); eventSystem.gameObject.SetActive(EventSystem.current == null || EventSystem.current == eventSystem); }
// 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)); }
// Token: 0x06001B22 RID: 6946 RVA: 0x0008E028 File Offset: 0x0008C228 private void SetUp(Type baseType, Type fallbackType, string actualTypeName, int descriptionIndex) { if (baseType == null || fallbackType == null) { return; } if (!baseType.IsSubclassOf(typeof(SDK_Base))) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("baseType", baseType, string.Format("'{0}' is not a subclass of the SDK base type '{1}'.", baseType.Name, typeof(SDK_Base).Name))); return; } if (!fallbackType.IsSubclassOf(baseType)) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("fallbackType", fallbackType, string.Format("'{0}' is not a subclass of the SDK base type '{1}'.", fallbackType.Name, baseType.Name))); return; } this.baseTypeName = baseType.FullName; this.fallbackTypeName = fallbackType.FullName; this.typeName = actualTypeName; if (string.IsNullOrEmpty(actualTypeName)) { this.type = fallbackType; this.originalTypeNameWhenFallbackIsUsed = null; this.descriptionIndex = -1; this.description = new SDK_DescriptionAttribute(typeof(SDK_FallbackSystem), 0); return; } Type type = Type.GetType(actualTypeName); if (type == null) { this.type = fallbackType; this.originalTypeNameWhenFallbackIsUsed = actualTypeName; this.descriptionIndex = -1; this.description = new SDK_DescriptionAttribute(typeof(SDK_FallbackSystem), 0); VRTK_Logger.Error(VRTK_Logger.GetCommonMessage(VRTK_Logger.CommonMessageKeys.SDK_NOT_FOUND, new object[] { actualTypeName, fallbackType.Name })); return; } if (!type.IsSubclassOf(baseType)) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("actualTypeName", actualTypeName, string.Format("'{0}' is not a subclass of the SDK base type '{1}'.", actualTypeName, baseType.Name))); return; } SDK_DescriptionAttribute[] descriptions = SDK_DescriptionAttribute.GetDescriptions(type); if (descriptions.Length <= descriptionIndex) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("descriptionIndex", descriptionIndex, string.Format("'{0}' has no '{1}' at that index.", actualTypeName, typeof(SDK_DescriptionAttribute).Name))); return; } this.type = type; this.originalTypeNameWhenFallbackIsUsed = null; this.descriptionIndex = descriptionIndex; this.description = descriptions[descriptionIndex]; }
/// <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; }
/// <summary> /// Creates a new attribute. /// </summary> /// <param name="prettyName">The pretty name of the SDK. Uniquely identifies the SDK. `null` and `string.Empty` aren't allowed.</param> /// <param name="symbol">The scripting define symbol needed for the SDK. Needs to be the same as `SDK_ScriptingDefineSymbolPredicateAttribute.symbol` to add and remove the scripting define symbol automatically using VRTK_SDKManager. `null` and `string.Empty` are allowed.</param> /// <param name="vrDeviceName">The name of the VR Device to load. Set to `null` or `string.Empty` if no VR Device is needed.</param> /// <param name="buildTargetGroupName">The name of a constant of `BuildTargetGroup`. `BuildTargetGroup.Unknown`, `null` and `string.Empty` are not allowed.</param> /// <param name="index">The index of this attribute, in case there are multiple on the same target.</param> public SDK_DescriptionAttribute(string prettyName, string symbol, string vrDeviceName, string buildTargetGroupName, int index = 0) { if (prettyName == null) { VRTK_Logger.Fatal(new ArgumentNullException("prettyName")); return; } if (prettyName == string.Empty) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("prettyName", prettyName, "An empty string isn't allowed.")); return; } this.prettyName = prettyName; this.symbol = symbol; this.vrDeviceName = string.IsNullOrEmpty(vrDeviceName) ? "None" : vrDeviceName; this.index = index; if (string.IsNullOrEmpty(buildTargetGroupName)) { buildTargetGroupName = "Unknown"; } #if UNITY_EDITOR Type buildTargetGroupType = typeof(BuildTargetGroup); try { buildTargetGroup = (BuildTargetGroup)Enum.Parse(buildTargetGroupType, buildTargetGroupName); } catch (Exception exception) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException(string.Format("'{0}' isn't a valid constant name of '{1}'.", buildTargetGroupName, buildTargetGroupType.Name), exception)); return; } if (buildTargetGroup == BuildTargetGroup.Unknown && !describesFallbackSDK) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("buildTargetGroupName", buildTargetGroupName, string.Format("'{0}' isn't allowed.", buildTargetGroupName))); return; } #endif }
// Token: 0x06001B1F RID: 6943 RVA: 0x0008DF58 File Offset: 0x0008C158 public static VRTK_SDKInfo[] Create <BaseType, FallbackType>(Type actualType) where BaseType : SDK_Base where FallbackType : BaseType { string fullName = actualType.FullName; SDK_DescriptionAttribute[] descriptions = SDK_DescriptionAttribute.GetDescriptions(actualType); if (descriptions.Length == 0) { VRTK_Logger.Fatal(string.Format("'{0}' doesn't specify any SDK descriptions via '{1}'.", fullName, typeof(SDK_DescriptionAttribute).Name)); return(new VRTK_SDKInfo[0]); } List <VRTK_SDKInfo> list = new List <VRTK_SDKInfo>(descriptions.Length); foreach (SDK_DescriptionAttribute sdk_DescriptionAttribute in descriptions) { VRTK_SDKInfo vrtk_SDKInfo = new VRTK_SDKInfo(); vrtk_SDKInfo.SetUp(typeof(BaseType), typeof(FallbackType), fullName, sdk_DescriptionAttribute.index); list.Add(vrtk_SDKInfo); } return(list.ToArray()); }
// Token: 0x06001276 RID: 4726 RVA: 0x00069208 File Offset: 0x00067408 public SDK_DescriptionAttribute(string prettyName, string symbol, string vrDeviceName, string buildTargetGroupName, int index = 0) { if (prettyName == null) { VRTK_Logger.Fatal(new ArgumentNullException("prettyName")); return; } if (prettyName == string.Empty) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("prettyName", prettyName, "An empty string isn't allowed.")); return; } this.prettyName = prettyName; this.symbol = symbol; this.vrDeviceName = (string.IsNullOrEmpty(vrDeviceName) ? "None" : vrDeviceName); this.index = index; if (string.IsNullOrEmpty(buildTargetGroupName)) { buildTargetGroupName = "Unknown"; } }
/// <summary> /// Creates new SDK infos for a type. /// </summary> /// <typeparam name="BaseType">The SDK base type. Must be a subclass of SDK_Base.</typeparam> /// <typeparam name="FallbackType">The SDK type to fall back on if problems occur. Must be a subclass of `BaseType.</typeparam> /// <param name="actualType">The SDK type to use. Must be a subclass of `BaseType.</param> /// <returns>Multiple newly created instances.</returns> public static VRTK_SDKInfo[] Create <BaseType, FallbackType>(Type actualType) where BaseType : SDK_Base where FallbackType : BaseType { string actualTypeName = actualType.FullName; SDK_DescriptionAttribute[] descriptions = SDK_DescriptionAttribute.GetDescriptions(actualType); if (descriptions.Length == 0) { VRTK_Logger.Fatal(string.Format("'{0}' doesn't specify any SDK descriptions via '{1}'.", actualTypeName, typeof(SDK_DescriptionAttribute).Name)); return(new VRTK_SDKInfo[0]); } HashSet <VRTK_SDKInfo> sdkInfos = new HashSet <VRTK_SDKInfo>(); foreach (SDK_DescriptionAttribute description in descriptions) { VRTK_SDKInfo sdkInfo = new VRTK_SDKInfo(); sdkInfo.SetUp(typeof(BaseType), typeof(FallbackType), actualTypeName, description.index); sdkInfos.Add(sdkInfo); } return(sdkInfos.ToArray()); }
private void SetBuildTarget(string groupName) { buildTargetGroupName = groupName; #if UNITY_EDITOR Type buildTargetGroupType = typeof(BuildTargetGroup); try { buildTargetGroup = (BuildTargetGroup)Enum.Parse(buildTargetGroupType, groupName); } catch (Exception exception) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException(string.Format("'{0}' isn't a valid constant name of '{1}'.", groupName, buildTargetGroupType.Name), exception)); return; } if (buildTargetGroup == BuildTargetGroup.Unknown) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("groupName", groupName, string.Format("'{0}' isn't allowed.", groupName))); return; } #endif }
// Token: 0x06001B79 RID: 7033 RVA: 0x0008F88C File Offset: 0x0008DA8C protected virtual void Show(VRTK_SDKSetupSwitcher.ViewingState viewingState) { if (viewingState != VRTK_SDKSetupSwitcher.ViewingState.Status) { if (viewingState != VRTK_SDKSetupSwitcher.ViewingState.Selection) { VRTK_Logger.Fatal(new ArgumentOutOfRangeException("viewingState", viewingState, null)); return; } this.AddSelectionButtons(); this.selectionPanel.gameObject.SetActive(true); this.statusPanel.gameObject.SetActive(false); } else { this.RemoveCreatedChooseButtons(); this.UpdateCurrentText(); this.selectionPanel.gameObject.SetActive(false); this.statusPanel.gameObject.SetActive(true); } this.fallbackCamera.gameObject.SetActive(VRTK_DeviceFinder.HeadsetCamera() == null); this.eventSystem.gameObject.SetActive(EventSystem.current == null || EventSystem.current == this.eventSystem); }
/// <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)); }