Initial Commit
This commit is contained in:
151
NoAutoGame/Editor/NoAutoGame.cs
Normal file
151
NoAutoGame/Editor/NoAutoGame.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DreadScripts.NoAutoGame
|
||||
{
|
||||
internal static class NoAutoGame
|
||||
{
|
||||
#region Constants
|
||||
private const string GAME_WINDOW_TYPE_ASSEMBLY_FULL_NAME = "UnityEditor.GameView, UnityEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null";
|
||||
private const string GAME_WINDOW_OPEN_SESS_KEY = "NoAutoGameWindowWasOpen";
|
||||
private const string LAST_WINDOWS_SESS_KEY = "NoAutoGameLastWindowsIDs";
|
||||
|
||||
private const string CLOSE_GAME_WINDOW_PREF_KEY = "NoAutoGameCloseGameWindow";
|
||||
private const string UNFOCUS_GAME_WINDOW_PREF_KEY = "NoAutoGameUnfocusGameView";
|
||||
private const int GAME_WINDOW_HANDLE_DELAY = 100;
|
||||
#endregion
|
||||
|
||||
private static Type _gameWindowType;
|
||||
private static Type gameWindowType => _gameWindowType ?? (_gameWindowType = Type.GetType(GAME_WINDOW_TYPE_ASSEMBLY_FULL_NAME));
|
||||
private static readonly PropertyInfo hasFocusProperty = typeof(EditorWindow).GetProperty("hasFocus", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
private static CancellationTokenSource cts;
|
||||
|
||||
private static bool closeGameWindow;
|
||||
private static bool unfocusGameWindow;
|
||||
private static EditorWindow[] previouslyFocusedWindows;
|
||||
private static void HandlePlaymodeChange(PlayModeStateChange change)
|
||||
{
|
||||
cts?.Cancel();
|
||||
|
||||
switch (change)
|
||||
{
|
||||
case PlayModeStateChange.ExitingEditMode:
|
||||
RememberWindows();
|
||||
break;
|
||||
case PlayModeStateChange.EnteredPlayMode:
|
||||
try
|
||||
{
|
||||
cts = new CancellationTokenSource();
|
||||
_ = HandleGameWindow(cts.Token);
|
||||
}
|
||||
catch(OperationCanceledException){}
|
||||
break;
|
||||
case PlayModeStateChange.EnteredEditMode:
|
||||
SessionState.EraseString(LAST_WINDOWS_SESS_KEY);
|
||||
if (!closeGameWindow && unfocusGameWindow && !SessionState.GetBool(GAME_WINDOW_OPEN_SESS_KEY, true))
|
||||
{
|
||||
var gameWindows = (EditorWindow[])Resources.FindObjectsOfTypeAll(gameWindowType);
|
||||
if (gameWindows.Any() && !gameWindows.Any(w => previouslyFocusedWindows.Contains(w)))
|
||||
foreach(var w in gameWindows)
|
||||
w.Close();
|
||||
}
|
||||
|
||||
previouslyFocusedWindows = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void RememberWindows()
|
||||
{
|
||||
if (unfocusGameWindow && hasFocusProperty != null)
|
||||
{
|
||||
var idList = string.Join(",", Resources.FindObjectsOfTypeAll<EditorWindow>()
|
||||
.Where(w => (bool) hasFocusProperty.GetValue(w))
|
||||
.Select(w => w.GetInstanceID().ToString()));
|
||||
|
||||
SessionState.SetString(LAST_WINDOWS_SESS_KEY, idList);
|
||||
}
|
||||
|
||||
if (gameWindowType == null) return;
|
||||
var gameWindows = Resources.FindObjectsOfTypeAll(gameWindowType);
|
||||
SessionState.SetBool(GAME_WINDOW_OPEN_SESS_KEY, gameWindows.Length > 0); }
|
||||
|
||||
private static async Task HandleGameWindow(CancellationToken ct)
|
||||
{
|
||||
if (!closeGameWindow && !unfocusGameWindow) return;
|
||||
var gameWindowWasOpen = SessionState.GetBool(GAME_WINDOW_OPEN_SESS_KEY, true);
|
||||
await Task.Delay(GAME_WINDOW_HANDLE_DELAY, ct);
|
||||
|
||||
if (closeGameWindow && !gameWindowWasOpen)
|
||||
{
|
||||
var windows = Resources.FindObjectsOfTypeAll(gameWindowType);
|
||||
foreach (var w in windows)
|
||||
{
|
||||
var ew = (EditorWindow)w;
|
||||
ew.Close();
|
||||
}
|
||||
} else if (unfocusGameWindow)
|
||||
{
|
||||
var previousWindowsFocusList = SessionState.GetString(LAST_WINDOWS_SESS_KEY, string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(previousWindowsFocusList)) return;
|
||||
|
||||
previouslyFocusedWindows = previousWindowsFocusList
|
||||
.Split(',').Select(int.Parse)
|
||||
.Select(EditorUtility.InstanceIDToObject)
|
||||
.OfType<EditorWindow>().Where(w => w != null).ToArray();
|
||||
foreach (var w in previouslyFocusedWindows)
|
||||
w.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Initialization
|
||||
[InitializeOnLoadMethod]
|
||||
private static void Initialize() => LoadVariables();
|
||||
private static void LoadVariables()
|
||||
{
|
||||
closeGameWindow = EditorPrefs.GetBool(CLOSE_GAME_WINDOW_PREF_KEY, false);
|
||||
unfocusGameWindow = EditorPrefs.GetBool(UNFOCUS_GAME_WINDOW_PREF_KEY, true);
|
||||
RefreshHook();
|
||||
}
|
||||
|
||||
private static void RefreshHook()
|
||||
{
|
||||
EditorApplication.playModeStateChanged -= HandlePlaymodeChange;
|
||||
if (closeGameWindow || unfocusGameWindow)
|
||||
EditorApplication.playModeStateChanged += HandlePlaymodeChange;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Menu Items
|
||||
[MenuItem("DreadTools/Utility/NoAutoGame/AutoUnfocus")]
|
||||
private static void ToggleUnfocusGameWindow()
|
||||
{
|
||||
bool newValue = !EditorPrefs.GetBool(UNFOCUS_GAME_WINDOW_PREF_KEY, true);
|
||||
EditorPrefs.SetBool(UNFOCUS_GAME_WINDOW_PREF_KEY, newValue);
|
||||
Debug.Log($"[NoAutoGame] AutoUnfocus is now {(newValue ? "enabled" : "disabled")}.");
|
||||
unfocusGameWindow = newValue;
|
||||
RefreshHook();
|
||||
}
|
||||
|
||||
[MenuItem("DreadTools/Utility/NoAutoGame/AutoClose")]
|
||||
private static void ToggleCloseGameWindow()
|
||||
{
|
||||
bool newValue = !EditorPrefs.GetBool(CLOSE_GAME_WINDOW_PREF_KEY, false);
|
||||
EditorPrefs.SetBool(CLOSE_GAME_WINDOW_PREF_KEY, newValue);
|
||||
Debug.Log($"[NoAutoGame] AutoClose is now {(newValue ? "enabled" : "disabled")}.");
|
||||
closeGameWindow = newValue;
|
||||
RefreshHook();
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
11
NoAutoGame/Editor/NoAutoGame.cs.meta
Normal file
11
NoAutoGame/Editor/NoAutoGame.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6c420c7dc39936499f795315373858c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
15
NoAutoGame/Editor/com.dreadscripts.noautogame.Editor.asmdef
Normal file
15
NoAutoGame/Editor/com.dreadscripts.noautogame.Editor.asmdef
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "com.dreadscripts.noautogame.Editor",
|
||||
"references": [],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0aba0aac9d6446439e0b33d153a8596
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user