protected override void LoadSettings()
        {
            for (int i = (int)ProjectSetting.BuildWsaUwp; i <= (int)ProjectSetting.DotNetScriptingBackend; i++)
            {
                switch ((ProjectSetting)i)
                {
                case ProjectSetting.BuildWsaUwp:
                case ProjectSetting.WsaEnableXR:
                case ProjectSetting.WsaUwpBuildToD3D:
                case ProjectSetting.DotNetScriptingBackend:
                    Values[(ProjectSetting)i] = true;
                    break;

                case ProjectSetting.TargetOccludedDevices:
                    Values[(ProjectSetting)i] = EditorPrefsUtility.GetEditorPref(Names[(ProjectSetting)i], false);
                    break;

                case ProjectSetting.SharingServices:
                    Values[(ProjectSetting)i] = EditorPrefsUtility.GetEditorPref(Names[(ProjectSetting)i], false);
                    break;

                case ProjectSetting.UseInputManagerAxes:
                    Values[(ProjectSetting)i] = EditorPrefsUtility.GetEditorPref(Names[(ProjectSetting)i], false);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
        /// <summary>
        /// Returns true the first time it is called within this editor session, and
        /// false for all subsequent calls.
        /// </summary>
        /// <remarks>
        /// The Unity Editor does not provide a callback for when a project is opened.
        /// InitializeOnLoad is triggered for all assembly reloads, including entering
        /// and exiting PlayMode, and whenever a script is modified and recompiled.
        ///
        /// To ensure execution only when opening a project in a new instance of the editor,
        /// store a timestamp in the editor key-value store whenever this function is called.
        /// The stored timestamp is then compared with the true start time of this editor
        /// instance.
        /// </remarks>
        private static bool IsNewEditorSession()
        {
            // Determine the launch date for this editor session using the current time, and the time since startup.
            DateTime thisLaunchDate = DateTime.UtcNow.AddSeconds(-EditorApplication.timeSinceStartup);

            // Determine the last known launch date of the editor by loading it from the PlayerPrefs cache.
            // If no key exists set the time to this session.
            string dateString = EditorPrefsUtility.GetEditorPref(AssemblyReloadTimestampKey, thisLaunchDate.ToString(CultureInfo.InvariantCulture));

            DateTime lastLaunchDate;

            DateTime.TryParse(dateString, out lastLaunchDate);

            // If the current session was launched later than the last known session start date, then this must be
            // a new session, and we can display the first-time prompt.
            if ((thisLaunchDate - lastLaunchDate).Seconds > 0)
            {
                EditorPrefsUtility.SetEditorPref(AssemblyReloadTimestampKey, dateString);
                return(true);
            }

            return(false);
        }
        private void OnEnable()
        {
            // Load settings
            _originalAppIconPath     = EditorPrefsUtility.GetEditorPref(EditorPrefsKey_AppIcon, _originalAppIconPath);
            _originalSplashImagePath = EditorPrefsUtility.GetEditorPref(EditorPrefsKey_SplashImage, _originalSplashImagePath);
            _outputDirectoryName     = EditorPrefsUtility.GetEditorPref(EditorPrefsKey_DirectoryName, _outputDirectoryName);

            if (!string.IsNullOrEmpty(_originalAppIconPath))
            {
                _originalAppIcon = AssetDatabase.LoadAssetAtPath <Texture2D>(_originalAppIconPath);
            }

            if (!string.IsNullOrEmpty(_originalSplashImagePath))
            {
                _originalSplashImage = AssetDatabase.LoadAssetAtPath <Texture2D>(_originalSplashImagePath);
            }

            if (string.IsNullOrEmpty(_outputDirectoryName))
            {
                _outputDirectoryName = Application.dataPath + "/" + InitialOutputDirectoryName;
            }

            defaultLabelWidth = EditorGUIUtility.labelWidth;
        }
        private void UpdateSettings(BuildTarget currentBuildTarget)
        {
            EditorPrefsUtility.SetEditorPref(Names[ProjectSetting.SharingServices], Values[ProjectSetting.SharingServices]);
            if (Values[ProjectSetting.SharingServices])
            {
                string sharingServiceDirectory = Directory.GetParent(Path.GetFullPath(Application.dataPath)).FullName + "\\External\\MixedRealityToolkit\\Sharing\\Server";
                string sharingServicePath      = sharingServiceDirectory + "\\SharingService.exe";
                if (!File.Exists(sharingServicePath) &&
                    EditorUtility.DisplayDialog("Attention!",
                                                "You're missing the Sharing Service Executable in your project.\n\n" +
                                                "Would you like to download the missing files from GitHub?\n\n" +
                                                "Alternatively, you can download it yourself or specify a target IP to connect to at runtime on the Sharing Stage.",
                                                "Yes", "Cancel"))
                {
                    using (var webRequest = UnityWebRequest.Get(SharingServiceURL))
                    {
#if UNITY_2017_2_OR_NEWER
                        webRequest.SendWebRequest();
#else
                        webRequest.Send();
#endif
                        while (!webRequest.isDone)
                        {
                            if (webRequest.downloadProgress > -1)
                            {
                                EditorUtility.DisplayProgressBar(
                                    "Downloading the SharingService executable from GitHub",
                                    "Progress...", webRequest.downloadProgress);
                            }
                        }

                        EditorUtility.ClearProgressBar();

#if UNITY_2017_1_OR_NEWER
                        if (webRequest.isNetworkError || webRequest.isHttpError)
#else
                        if (webRequest.isError)
#endif
                        {
                            Debug.LogError("Network Error: " + webRequest.error);
                        }
                        else
                        {
                            byte[] sharingServiceData = webRequest.downloadHandler.data;
                            Directory.CreateDirectory(sharingServiceDirectory);
                            File.WriteAllBytes(sharingServicePath, sharingServiceData);
                        }
                    }
                }
                else
                {
                    Debug.LogFormat("Alternatively, you can download from this link: {0}", SharingServiceURL);
                }

                PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.InternetClientServer, true);
                PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.PrivateNetworkClientServer, true);
            }
            else
            {
                PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.InternetClient, false);
                PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.InternetClientServer, false);
                PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.PrivateNetworkClientServer, false);
            }

            bool useToolkitAxes = Values[ProjectSetting.UseInputManagerAxes];

            if (useToolkitAxes != EditorPrefsUtility.GetEditorPref(Names[ProjectSetting.UseInputManagerAxes], false))
            {
                EditorPrefsUtility.SetEditorPref(Names[ProjectSetting.UseInputManagerAxes], useToolkitAxes);

                // Grabs the actual asset file into a SerializedObject, so we can iterate through it and edit it.
                inputManagerAsset = new SerializedObject(AssetDatabase.LoadAssetAtPath("ProjectSettings/InputManager.asset", typeof(UnityEngine.Object)));

                if (useToolkitAxes)
                {
                    foreach (InputManagerAxis axis in newInputAxes)
                    {
                        if (!DoesAxisNameExist(axis.Name))
                        {
                            AddAxis(axis);
                        }
                    }
                }
                else
                {
                    foreach (InputManagerAxis axis in newInputAxes)
                    {
                        if (DoesAxisNameExist(axis.Name))
                        {
                            RemoveAxis(axis.Name);
                        }
                    }

                    foreach (InputManagerAxis axis in obsoleteInputAxes)
                    {
                        if (DoesAxisNameExist(axis.Name))
                        {
                            RemoveAxis(axis.Name);
                        }
                    }
                }

                inputManagerAsset.ApplyModifiedProperties();
            }

            if (currentBuildTarget != BuildTarget.WSAPlayer)
            {
                AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
                Close();
                return;
            }

            EditorUserBuildSettings.wsaUWPBuildType = Values[ProjectSetting.WsaUwpBuildToD3D]
                ? WSAUWPBuildType.D3D
                : WSAUWPBuildType.XAML;

            UnityEditorInternal.VR.VREditor.SetVREnabledOnTargetGroup(BuildTargetGroup.WSA, Values[ProjectSetting.WsaEnableXR]);

            if (!Values[ProjectSetting.WsaEnableXR])
            {
                EditorUserBuildSettings.wsaSubtarget = WSASubtarget.AnyDevice;
                UnityEditorInternal.VR.VREditor.SetVREnabledDevicesOnTargetGroup(BuildTargetGroup.WSA, new[] { "None" });
                PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.HumanInterfaceDevice, false);
                BuildDeployPrefs.BuildPlatform = "Any CPU";
            }
            else
            {
#if !UNITY_2017_2_OR_NEWER
                Values[ProjectSetting.TargetOccludedDevices] = false;
#endif
                if (!Values[ProjectSetting.TargetOccludedDevices])
                {
                    EditorUserBuildSettings.wsaSubtarget = WSASubtarget.HoloLens;
#if UNITY_2017_2_OR_NEWER
                    UnityEditorInternal.VR.VREditor.SetVREnabledDevicesOnTargetGroup(BuildTargetGroup.WSA, new[] { "WindowsMR" });
#else
                    UnityEditorInternal.VR.VREditor.SetVREnabledDevicesOnTargetGroup(BuildTargetGroup.WSA, new[] { "HoloLens" });
#endif
                    PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.HumanInterfaceDevice, Values[ProjectSetting.UseInputManagerAxes]);
                    BuildDeployPrefs.BuildPlatform = "x86";

                    for (var i = 0; i < QualitySettings.names.Length; i++)
                    {
                        QualitySettings.DecreaseLevel(true);
                    }
                }
                else
                {
                    EditorUserBuildSettings.wsaSubtarget = WSASubtarget.PC;
                    UnityEditorInternal.VR.VREditor.SetVREnabledDevicesOnTargetGroup(BuildTargetGroup.WSA, new[] { "WindowsMR" });
                    PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.HumanInterfaceDevice, false);
                    BuildDeployPrefs.BuildPlatform = "x64";

                    for (var i = 0; i < QualitySettings.names.Length; i++)
                    {
                        QualitySettings.IncreaseLevel(true);
                    }
                }

                int currentQualityLevel = QualitySettings.GetQualityLevel();

                // HACK: Edits QualitySettings.asset Directly
                // TODO: replace with friendlier version that uses built in APIs when Unity fixes or makes available.
                // See: http://answers.unity3d.com/questions/886160/how-do-i-change-qualitysetting-for-my-platform-fro.html
                try
                {
                    // Find the WSA element under the platform quality list and replace it's value with the current level.
                    string settingsPath   = "ProjectSettings/QualitySettings.asset";
                    string matchPattern   = @"(m_PerPlatformDefaultQuality.*Windows Store Apps:) (\d+)";
                    string replacePattern = @"$1 " + currentQualityLevel;

                    string settings = File.ReadAllText(settingsPath);
                    settings = Regex.Replace(settings, matchPattern, replacePattern, RegexOptions.Singleline);

                    File.WriteAllText(settingsPath, settings);
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
            }

            EditorPrefsUtility.SetEditorPref(Names[ProjectSetting.TargetOccludedDevices], Values[ProjectSetting.TargetOccludedDevices]);

            PlayerSettings.SetScriptingBackend(BuildTargetGroup.WSA,
                                               Values[ProjectSetting.DotNetScriptingBackend]
                    ? ScriptingImplementation.WinRTDotNET
                    : ScriptingImplementation.IL2CPP);

            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            Close();
        }
 private static void SaveSettings()
 {
     EditorPrefsUtility.SetEditorPref(EditorPrefsKey_AppIcon, _originalAppIconPath);
     EditorPrefsUtility.SetEditorPref(EditorPrefsKey_SplashImage, _originalSplashImagePath);
     EditorPrefsUtility.SetEditorPref(EditorPrefsKey_DirectoryName, _outputDirectoryName);
 }