Пример #1
0
        /// <summary>
        /// Manages (i.e. adds and removes) the scripting define symbols of the <see cref="PlayerSettings"/> for the currently set SDK infos. 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="ignoreAutoManageScriptDefines">Whether to ignore <see cref="autoManageScriptDefines"/> while deciding to manage.</param>
        /// <param name="ignoreIsActiveAndEnabled">Whether to ignore <see cref="Behaviour.isActiveAndEnabled"/> while deciding to manage.</param>
        /// <returns>Whether the <see cref="PlayerSettings"/>' scripting define symbols were changed.</returns>
        public bool ManageScriptingDefineSymbols(bool ignoreAutoManageScriptDefines, bool ignoreIsActiveAndEnabled)
        {
            if (!((ignoreAutoManageScriptDefines || autoManageScriptDefines) && (ignoreIsActiveAndEnabled || isActiveAndEnabled)))
            {
                return(false);
            }

            //get valid BuildTargetGroups
            BuildTargetGroup[] targetGroups = Enum.GetValues(typeof(BuildTargetGroup)).Cast <BuildTargetGroup>().Where(group =>
            {
                if (group == BuildTargetGroup.Unknown)
                {
                    return(false);
                }

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

                return(targetGroupFieldInfo != null && targetGroupFieldInfo.GetCustomAttributes(typeof(ObsoleteAttribute), false).Length == 0);
            }).ToArray();
            var newSymbolsByTargetGroup = new Dictionary <BuildTargetGroup, HashSet <string> >(targetGroups.Length);

            //get current non-removable scripting define symbols
            foreach (BuildTargetGroup targetGroup in targetGroups)
            {
                IEnumerable <string> nonSDKSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup)
                                                     .Split(';')
                                                     .Where(symbol => !symbol.StartsWith(SDK_ScriptingDefineSymbolPredicateAttribute.RemovableSymbolPrefix, StringComparison.Ordinal));
                newSymbolsByTargetGroup[targetGroup] = new HashSet <string>(nonSDKSymbols);
            }

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

            //get scripting define symbols and check whether the predicates allow us to add the symbols
            foreach (ScriptingDefineSymbolPredicateInfo predicateInfo in AvailableScriptingDefineSymbolPredicateInfos)
            {
                string symbol = predicateInfo.attribute.symbol;
                if (!sdkSymbols.Contains(symbol) && !activeSymbols.Contains(symbol))
                {
                    continue;
                }

                MethodInfo methodInfo = predicateInfo.methodInfo;
                if (!(bool)methodInfo.Invoke(null, null))
                {
                    continue;
                }

                //add symbols from all predicate attributes on the method since multiple ones are allowed
                var allAttributes = (SDK_ScriptingDefineSymbolPredicateAttribute[])methodInfo.GetCustomAttributes(typeof(SDK_ScriptingDefineSymbolPredicateAttribute), false);
                foreach (SDK_ScriptingDefineSymbolPredicateAttribute attribute in allAttributes)
                {
                    BuildTargetGroup buildTargetGroup = attribute.buildTargetGroup;
                    HashSet <string> newSymbols;
                    if (!newSymbolsByTargetGroup.TryGetValue(buildTargetGroup, out newSymbols))
                    {
                        newSymbols = new HashSet <string>();
                        newSymbolsByTargetGroup[buildTargetGroup] = newSymbols;
                    }

                    newSymbols.Add(attribute.symbol);
                }
            }

            var changedSymbols = false;

            //apply new set of scripting define symbols
            foreach (KeyValuePair <BuildTargetGroup, HashSet <string> > keyValuePair in newSymbolsByTargetGroup)
            {
                BuildTargetGroup targetGroup    = keyValuePair.Key;
                string[]         currentSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup)
                                                  .Split(';')
                                                  .Distinct()
                                                  .OrderBy(symbol => symbol, StringComparer.Ordinal)
                                                  .ToArray();
                string[] newSymbols = keyValuePair.Value.OrderBy(symbol => symbol, StringComparer.Ordinal).ToArray();

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

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

                string[] removedSymbols = currentSymbols.Except(newSymbols).ToArray();
                if (removedSymbols.Length > 0)
                {
                    Debug.Log("Scripting Define Symbols removed from [Project Settings->Player]: " + string.Join(", ", removedSymbols));
                }

                string[] addedSymbols = newSymbols.Except(currentSymbols).ToArray();
                if (addedSymbols.Length > 0)
                {
                    Debug.Log("Scripting Define Symbols added To [Project Settings->Player]: " + string.Join(", ", addedSymbols));
                }

                if (!changedSymbols)
                {
                    changedSymbols = removedSymbols.Length > 0 || addedSymbols.Length > 0;
                }
            }

            return(changedSymbols);
        }
Пример #2
0
        /// <summary>
        /// Handles SDK selection during startup. Must be called before setupping any SDK specific stuff.
        /// </summary>
        private void SetupSDK()
        {
            // Check if we even have to do any SDK selection
            bool needsSDKSetup = automaticSDKSelection || (actualBoundaries == null && actualHeadset == null && actualLeftController == null && actualRightController == null);

            if (!needsSDKSetup)
            {
                return;
            }

            string selectedSDK = "Fallback";

            // Heuristic SDK detection
            if (automaticSDKSelection)
            {
                if (!VRDevice.isPresent)
                {
                    selectedSDK = "Simulator";
                }
                else
                {
                    if (VRDevice.model.Contains("Oculus") || VRDevice.model.Contains("Rift"))
                    {
                        selectedSDK = "OculusVR";
                    }
                    else
                    {
                        // Assume everyone else except Oculus uses SteamVR
                        selectedSDK = "SteamVR";
                    }
                }

                // Check for command line SDKs. These override all the previous selections.
                var args = System.Environment.GetCommandLineArgs();
                foreach (var arg in args)
                {
                    if (arg.Equals("--vr-none"))
                    {
                        selectedSDK = "Fallback";
                    }
                    if (arg.Equals("--vr-oculus"))
                    {
                        selectedSDK = "OculusVR";
                    }
                    if (arg.Equals("--vr-steam"))
                    {
                        selectedSDK = "SteamVR";
                    }
                    if (arg.Equals("--vr-simulator"))
                    {
                        selectedSDK = "Simulator";
                    }
                }

                Debug.Log("Selected VR SDK: " + selectedSDK);

                // Set correct individual SDKs
                systemSDKInfo     = GetSDK(selectedSDK, AvailableSystemSDKInfos);
                boundariesSDKInfo = GetSDK(selectedSDK, AvailableBoundariesSDKInfos);
                headsetSDKInfo    = GetSDK(selectedSDK, AvailableHeadsetSDKInfos);
                controllerSDKInfo = GetSDK(selectedSDK, AvailableControllerSDKInfos);

                // Load the SDK camera rig if one has been assigned
                int sdkIndex  = AvailableSystemSDKInfos.IndexOf(GetSDK(selectedSDK));
                var sdkPrefab = automaticSDKPrefabList[sdkIndex];
                if (sdkPrefab != null)
                {
                    var go = Instantiate(sdkPrefab) as GameObject;
                    if (go != null)
                    {
                        // Remove (Clone) from the name of the instantiated game object, otherwise SDKs don't work properly
                        // as they find the gameobjects by their name.
                        go.name = go.name.Replace("(Clone)", "");
                    }
                }
                // Disable VR if we don't have a true VR SDK
                if (selectedSDK == "Fallback" || selectedSDK == "Simulator")
                {
                    VRSettings.enabled = false;
                    VRSettings.LoadDeviceByName("None");
                }

                // Assign VRTK components to the newly instantiated rig
                var playareaTransform = GetBoundariesSDK().GetPlayArea();
                actualBoundaries = (playareaTransform ? playareaTransform.gameObject : null);

                var headsetTransform = GetHeadsetSDK().GetHeadset();
                actualHeadset = (headsetTransform ? headsetTransform.gameObject : null);

                var controllerLeft = GetControllerSDK().GetControllerLeftHand(true);
                actualLeftController = controllerLeft;

                var controllerRight = GetControllerSDK().GetControllerRightHand(true);
                actualRightController = controllerRight;

                var controllerAliasLeft = GetControllerSDK().GetControllerModel(SDK_BaseController.ControllerHand.Left);
                modelAliasLeftController = controllerAliasLeft;

                var controllerAliasRight = GetControllerSDK().GetControllerModel(SDK_BaseController.ControllerHand.Right);
                modelAliasRightController = controllerAliasRight;
            }
        }
Пример #3
0
        /// <summary>
        /// Manages (i.e. adds and removes) the scripting define symbols of the PlayerSettings for the currently set SDK infos.
        /// 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="ignoreAutoManageScriptDefines">Whether to ignore `autoManageScriptDefines` while deciding to manage.</param>
        /// <param name="ignoreIsActiveAndEnabled">Whether to ignore `Behaviour.isActiveAndEnabled` while deciding to manage.</param>
        /// <returns>Whether the PlayerSettings' scripting define symbols were changed.</returns>
        public bool ManageScriptingDefineSymbols(bool ignoreAutoManageScriptDefines, bool ignoreIsActiveAndEnabled)
        {
            if (!((ignoreAutoManageScriptDefines || autoManageScriptDefines) && (ignoreIsActiveAndEnabled || isActiveAndEnabled)))
            {
                return(false);
            }

            //get valid BuildTargetGroups
            BuildTargetGroup[] targetGroups = VRTK_SharedMethods.GetValidBuildTargetGroups();
            Dictionary <BuildTargetGroup, HashSet <string> > newSymbolsByTargetGroup = new Dictionary <BuildTargetGroup, HashSet <string> >(targetGroups.Length);

            //get current non-removable scripting define symbols
            foreach (BuildTargetGroup targetGroup in targetGroups)
            {
                IEnumerable <string> nonSDKSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup)
                                                     .Split(';')
                                                     .Where(symbol => !symbol.StartsWith(SDK_ScriptingDefineSymbolPredicateAttribute.RemovableSymbolPrefix, StringComparison.Ordinal));
                newSymbolsByTargetGroup[targetGroup] = new HashSet <string>(nonSDKSymbols);
            }

            VRTK_SDKInfo[] availableSDKInfos = AvailableSystemSDKInfos
                                               .Concat(AvailableBoundariesSDKInfos)
                                               .Concat(AvailableHeadsetSDKInfos)
                                               .Concat(AvailableControllerSDKInfos)
                                               .ToArray();

            HashSet <SDK_DescriptionAttribute> descriptions = new HashSet <SDK_DescriptionAttribute>(
                availableSDKInfos.Select(info => info.description)
                .Where(description => !description.describesFallbackSDK)
                );
            HashSet <string> activeSymbols = new HashSet <string>(activeScriptingDefineSymbolsWithoutSDKClasses.Select(attribute => attribute.symbol));

            //get scripting define symbols and check whether the predicates allow us to add the symbols
            foreach (ScriptingDefineSymbolPredicateInfo predicateInfo in AvailableScriptingDefineSymbolPredicateInfos)
            {
                SDK_ScriptingDefineSymbolPredicateAttribute predicateAttribute = predicateInfo.attribute;
                string symbol = predicateAttribute.symbol;
                if (!activeSymbols.Contains(symbol) &&
                    !descriptions.Any(description => description.symbol == symbol &&
                                      description.buildTargetGroup == predicateAttribute.buildTargetGroup))
                {
                    continue;
                }

                MethodInfo methodInfo = predicateInfo.methodInfo;
                if (!(bool)methodInfo.Invoke(null, null))
                {
                    continue;
                }

                //add symbols from all predicate attributes on the method since multiple ones are allowed
                SDK_ScriptingDefineSymbolPredicateAttribute[] allAttributes = (SDK_ScriptingDefineSymbolPredicateAttribute[])methodInfo.GetCustomAttributes(typeof(SDK_ScriptingDefineSymbolPredicateAttribute), false);
                foreach (SDK_ScriptingDefineSymbolPredicateAttribute attribute in allAttributes)
                {
                    BuildTargetGroup buildTargetGroup = attribute.buildTargetGroup;
                    HashSet <string> newSymbols;
                    if (!newSymbolsByTargetGroup.TryGetValue(buildTargetGroup, out newSymbols))
                    {
                        newSymbols = new HashSet <string>();
                        newSymbolsByTargetGroup[buildTargetGroup] = newSymbols;
                    }

                    newSymbols.Add(attribute.symbol);
                }
            }

            bool changedSymbols = false;

            //apply new set of scripting define symbols
            foreach (KeyValuePair <BuildTargetGroup, HashSet <string> > keyValuePair in newSymbolsByTargetGroup)
            {
                BuildTargetGroup targetGroup    = keyValuePair.Key;
                string[]         currentSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(targetGroup)
                                                  .Split(';')
                                                  .Distinct()
                                                  .OrderBy(symbol => symbol, StringComparer.Ordinal)
                                                  .ToArray();
                string[] newSymbols = keyValuePair.Value.OrderBy(symbol => symbol, StringComparer.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)));
                }

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

                if (!changedSymbols)
                {
                    changedSymbols = removedSymbols.Length > 0 || addedSymbols.Length > 0;
                }
            }

            return(changedSymbols);
        }