Skip to content

Instantly share code, notes, and snippets.

@RodGreen
Created September 12, 2019 21:54
Show Gist options
  • Save RodGreen/8d5f5452c459755d9bf6bad1015ef194 to your computer and use it in GitHub Desktop.
Save RodGreen/8d5f5452c459755d9bf6bad1015ef194 to your computer and use it in GitHub Desktop.
Automatically switches editor shortcut profile when playing Unity3D
using UnityEngine;
using UnityEditor;
using UnityEditor.ShortcutManagement;
using System.Linq;
[InitializeOnLoad]
public class SwitchShortcutsProfileOnPlay
{
private const string PlayingProfileId = "Playing";
private static string _activeProfileId;
private static bool _switched;
static SwitchShortcutsProfileOnPlay()
{
EditorApplication.playModeStateChanged += DetectPlayModeState;
}
private static void SetActiveProfile(string profileId)
{
Debug.Log($"Activating Shortcut profile \"{profileId}\"");
ShortcutManager.instance.activeProfileId = profileId;
}
private static void DetectPlayModeState(PlayModeStateChange state)
{
switch (state)
{
case PlayModeStateChange.EnteredPlayMode:
OnEnteredPlayMode();
break;
case PlayModeStateChange.ExitingPlayMode:
OnExitingPlayMode();
break;
}
}
private static void OnExitingPlayMode()
{
if (!_switched)
return;
_switched = false;
SetActiveProfile(_activeProfileId);
}
private static void OnEnteredPlayMode()
{
_activeProfileId = ShortcutManager.instance.activeProfileId;
if (_activeProfileId.Equals(PlayingProfileId))
return; // Same as active
var allProfiles = ShortcutManager.instance.GetAvailableProfileIds().ToList();
if (!allProfiles.Contains(PlayingProfileId))
return; // Couldn't find PlayingProfileId
_switched = true;
SetActiveProfile(PlayingProfileId);
}
}
@Aeroxia
Copy link

Aeroxia commented May 9, 2025

I found it sometimes didn't always switch the profile back to the main active profile when exiting play mode. It seems the static variable _activeProfileId was getting reset when the script was reloaded when switching modes (domain reloads and possible race conditions). This seems to work more reliably (Unity 2021.3):

using UnityEditor;
using UnityEditor.ShortcutManagement;
using System.Linq;
using UnityEngine;

//Originally from: https://gist.github.com/RodGreen/8d5f5452c459755d9bf6bad1015ef194
//Linked from: https://forum.unity.com/threads/unwanted-editor-hotkeys-in-game-mode.182073/
//Much modified

namespace Editor
{
    [InitializeOnLoad]
    public class SwitchShortcutsProfileOnPlay
    {
        private const string PlayingProfileId = "Playing";
        private const string ProfileEditorPrefKey = "StoredShortcutProfile";
        private static bool _switched;

        static SwitchShortcutsProfileOnPlay()
        {
            EditorApplication.playModeStateChanged += DetectPlayModeState;
        }

        private static string ActiveProfileId
        {
            get => EditorPrefs.GetString(ProfileEditorPrefKey, "");
            set => EditorPrefs.SetString(ProfileEditorPrefKey, value);
        }

        private static void SetActiveProfile(string profileId)
        {
            if (string.IsNullOrEmpty(profileId)
                || !ShortcutManager.instance.GetAvailableProfileIds().Contains(profileId))
            {
                Debug.LogWarning($"Attempted to set invalid shortcut profile: {profileId}");
                return;
            }

            ShortcutManager.instance.activeProfileId = profileId;
            // Debug.Log($"Successfully switched to shortcut profile: {profileId}");
        }

        private static void DetectPlayModeState(PlayModeStateChange state)
        {
            // Debug.Log($"Play mode state changed to: {state}");

            switch (state)
            {
                case PlayModeStateChange.ExitingEditMode:
                    ActiveProfileId = ShortcutManager.instance.activeProfileId;
                    // Debug.Log($"Stored active profile: {ActiveProfileId}");
                    break;

                case PlayModeStateChange.EnteredPlayMode:
                    if (!ShortcutManager.instance.activeProfileId.Equals(PlayingProfileId))
                    {
                        _switched = true;
                        SetActiveProfile(PlayingProfileId);
                    }

                    /* BE CAREFUL: Uncommenting this will completely clear the Playing profile of shortcuts, leaving them all unbound */
                    // if (ShortcutManager.instance.activeProfileId.Equals(PlayingProfileId))
                    // {
                    //    foreach (string pid in ShortcutManager.instance.GetAvailableShortcutIds())
                    //        ShortcutManager.instance.RebindShortcut(pid, ShortcutBinding.empty);
                    // }

                    break;

                case PlayModeStateChange.ExitingPlayMode:
                    // Debug.Log($"Exiting play mode. Stored profile is: {ActiveProfileId}");
                    if (_switched && !string.IsNullOrEmpty(ActiveProfileId))
                    {
                        EditorApplication.delayCall += () =>
                        {
                            // Debug.Log($"Restoring profile to: {ActiveProfileId}");
                            SetActiveProfile(ActiveProfileId);
                            _switched = false;
                        };
                    }

                    break;
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment