Last active
September 30, 2024 07:15
-
-
Save CSaratakij/bf6e7eb0108e963c59c833ad5a9f7a0a to your computer and use it in GitHub Desktop.
Quick change unity player setting build type from Mono to IL2CPP menu item "Help/Quick change build type/..."
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Note : adhocs for unity 2022.3.31 | |
TODO : Need to Support Unity 6 with the new callback : https://docs.unity3d.com/6000.0/Documentation/ScriptReference/EditorApplication.UpdateMainWindowTitle.html | |
and the new force update window title method : https://docs.unity3d.com/6000.0/Documentation/ScriptReference/EditorApplication.UpdateMainWindowTitle.html | |
*/ | |
#if UNITY_2022_3_31 | |
#define EDITOR_ALLOW_BUILDTYPE_STATUS | |
#endif | |
#if UNITY_EDITOR && UNITY_EDITOR_WIN && EDITOR_ALLOW_BUILDTYPE_STATUS | |
using System; | |
using System.Reflection; | |
using UnityEditor; | |
namespace Game.EditorUtility | |
{ | |
internal static class BuildTypeEditorWindowTitleStatus | |
{ | |
internal static event Action<string> OnInternalEditorUpdateMainWindowTitle; | |
internal static event Action<bool> OnEditorApplicationFocusChanged; | |
private static bool isPreviousFocus = false; | |
private static bool isCurrentFocus = false; | |
internal static string CurrentCustomEditorWindowTitle = ""; | |
private static string CurrentInternalEditorWindowTitle = ""; | |
private static object CurrentInternalApplicationTitleDescriptor = null; | |
private static Delegate updateMainWindowTitleEventHandler = null; | |
internal static bool IsInternalApplicationTitleDescriptorDirty => (CurrentInternalApplicationTitleDescriptor == null); | |
[InitializeOnLoadMethod] | |
private static void Initialize() | |
{ | |
Reset(); | |
try | |
{ | |
EventInfo eventInfo = GetUpdateMainWindowTitleEvent(out var bindingFlags); | |
if (eventInfo != null) | |
{ | |
MethodInfo callbackMethodInfo = typeof(BuildTypeEditorWindowTitleStatus).GetMethod(nameof(OnUpdateMainWindowTitleHandler), BindingFlags.Static | BindingFlags.NonPublic); | |
updateMainWindowTitleEventHandler = Delegate.CreateDelegate(eventInfo.EventHandlerType, callbackMethodInfo, throwOnBindFailure: true); | |
MethodInfo addEventHandlerMethodInfo = eventInfo.GetAddMethod(nonPublic: true); | |
addEventHandlerMethodInfo.Invoke(null, new object[] { updateMainWindowTitleEventHandler }); | |
} | |
else | |
{ | |
throw new Exception($"{nameof(BuildTypeEditorWindowTitleStatus)}: target event 'updateMainWindowTitle' not found in this unity version"); | |
} | |
isPreviousFocus = isCurrentFocus; | |
isCurrentFocus = EditorApplication.isFocused; | |
EditorApplication.focusChanged += OnEditorApplicationFocusChangedHandler; | |
EditorApplication.playModeStateChanged += OnPlayModeStateChange; | |
QuickChangeBuildTypeMenu.OnBuildTypeChanged += OnBuildTypeChanged; | |
} | |
catch (Exception e) | |
{ | |
UnityEngine.Debug.LogError(e); | |
} | |
void Reset() | |
{ | |
isPreviousFocus = false; | |
isCurrentFocus = false; | |
CurrentInternalApplicationTitleDescriptor = null; | |
} | |
} | |
private static void OnEditorApplicationFocusChangedHandler(bool isFocused) | |
{ | |
isPreviousFocus = isCurrentFocus; | |
isCurrentFocus = isFocused; | |
bool isFocusDirty = (isPreviousFocus != isCurrentFocus); | |
if (isFocusDirty) | |
{ | |
isPreviousFocus = isCurrentFocus; | |
ForceBuildInternalMainWindowTitle(); | |
} | |
OnEditorApplicationFocusChanged?.Invoke(isFocused); | |
} | |
private static void OnPlayModeStateChange(PlayModeStateChange state) | |
{ | |
if (state == PlayModeStateChange.EnteredEditMode) | |
{ | |
ForceBuildInternalMainWindowTitle(); | |
} | |
} | |
private static void OnBuildTypeChanged() | |
{ | |
ForceBuildInternalMainWindowTitle(); | |
} | |
// Note : can only update window title in the exact reference of application title descriptor in this callback only | |
private static void OnUpdateMainWindowTitleHandler(object descriptor) | |
{ | |
BuildType? buildType = GetCurrentBuildType(); | |
if (buildType != null) | |
{ | |
UpdateWindowTitle(descriptor, buildType.Value); | |
} | |
} | |
private static void UpdateWindowTitle(object descriptor, BuildType buildType) | |
{ | |
try | |
{ | |
if (descriptor == null) | |
{ | |
return; | |
} | |
FieldInfo editorWindowTitleFieldInfo = descriptor.GetType()?.GetField("title"); | |
if (editorWindowTitleFieldInfo == null) | |
{ | |
return; | |
} | |
string internalWindowTitle = (editorWindowTitleFieldInfo.GetValue(descriptor) as string); | |
string customWindowTitle = $"{internalWindowTitle} <{buildType}>"; | |
CurrentInternalApplicationTitleDescriptor = descriptor; | |
CurrentInternalEditorWindowTitle = internalWindowTitle; | |
CurrentCustomEditorWindowTitle = customWindowTitle; | |
editorWindowTitleFieldInfo.SetValue(descriptor, customWindowTitle); | |
OnInternalEditorUpdateMainWindowTitle?.Invoke(customWindowTitle); | |
} | |
catch (Exception e) | |
{ | |
UnityEngine.Debug.LogError(e); | |
} | |
} | |
private static bool ForceBuildInternalMainWindowTitle() | |
{ | |
try | |
{ | |
MethodInfo methodInfo_BuildMainWindowTitle = typeof(EditorApplication).GetMethod("BuildMainWindowTitle", BindingFlags.Static | BindingFlags.NonPublic); | |
MethodInfo methodInfo_UpdateMainWindowTitle = typeof(EditorApplication).GetMethod("UpdateMainWindowTitle", BindingFlags.Static | BindingFlags.NonPublic); | |
bool isValid = (methodInfo_BuildMainWindowTitle != null) && (methodInfo_UpdateMainWindowTitle != null); | |
if (!isValid) | |
{ | |
return false; | |
} | |
// Hacks : force build internal main window title to get the lastest application title descriptor | |
if (IsInternalApplicationTitleDescriptorDirty) | |
{ | |
methodInfo_BuildMainWindowTitle?.Invoke(null, null); | |
} | |
// Hacks : make sure window title gui update from application title descriptor | |
methodInfo_UpdateMainWindowTitle?.Invoke(null, null); | |
return true; | |
} | |
catch (Exception e) | |
{ | |
UnityEngine.Debug.LogError(e); | |
return false; | |
} | |
} | |
internal static void ForceUpdateMainWindowTitle(object reflection_ApplicationTitleDescriptor) | |
{ | |
try | |
{ | |
EventInfo eventInfo = GetUpdateMainWindowTitleEvent(out var bindingFlags); | |
if (eventInfo == null) | |
{ | |
return; | |
} | |
FieldInfo fieldInfo = typeof(EditorApplication).GetField(eventInfo.Name, bindingFlags); | |
if (fieldInfo != null) | |
{ | |
var eventDelegate = (fieldInfo.GetValue(null) as Delegate); | |
eventDelegate?.DynamicInvoke(new object[] { reflection_ApplicationTitleDescriptor }); | |
} | |
} | |
catch (Exception e) | |
{ | |
UnityEngine.Debug.LogError(e); | |
} | |
} | |
private static EventInfo GetUpdateMainWindowTitleEvent(out BindingFlags bindingFlags) | |
{ | |
bindingFlags = BindingFlags.Static | BindingFlags.NonPublic; | |
try | |
{ | |
EventInfo targetEvent = typeof(EditorApplication).GetEvent("updateMainWindowTitle", bindingFlags); | |
return targetEvent; | |
} | |
catch (Exception e) | |
{ | |
UnityEngine.Debug.LogError(e); | |
return null; | |
} | |
} | |
private static BuildType? GetCurrentBuildType() | |
{ | |
BuildTargetGroup currentBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; | |
ScriptingImplementation currentScriptingImplementation = PlayerSettings.GetScriptingBackend(currentBuildTargetGroup); | |
return currentScriptingImplementation switch | |
{ | |
ScriptingImplementation.Mono2x => BuildType.Mono, | |
ScriptingImplementation.IL2CPP => BuildType.IL2CPP, | |
_ => null | |
}; | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment