How do I make auto-refresh turn into the same functionality as the play button?

My question: I believe I need to know the System Keyword for determining when a hotkey is pressed or when refresh is pressed, not just when processed. Anyone know this?

The reason:

Video of Problem that costs Unity devs thousands of hours of lost man hours each week:

People have told me there are only two options to compile:

  1. Let it auto refresh when code is changed and you tab to unity.

or

  1. Ctrl+r to refresh manually.

Let me explain why both of these options waste developer’s time.

Problems:

  1. Let it auto refresh when code is changed and you tab to unity…

Use Case: So you change code… But while coding, you wanted to see a number in the inspector about a game object to set as a variable. You alt tab to unity… It starts compiling. You need to wait 7 seconds. Then you get your number. You alt tab back to code and resume.

Net result: You lost 7 seconds of compile you didn’t need.

  1. Alternatively you could uncheck autorefresh, but this leads to worse problems since you need to Ctrl+r to refresh manually.

Use Case: You edit code, forget to ctrl+r before play. Then your game looks bugged still, so you edit code over and over for about 10 minutes then remember,“Oh yeah, Unity is forcing me to remember to ctrl+r” then you do that, revert a zillion changes, take another 5 minutes, and you’re wondering why you have “auto refresh?” checked.

Net result 15 minutes + wasted.

Solution: Give us an option to “Compile if needed when play button hit”, like every other sane IDE.


I asked this in another forum.

The solution was to uncheck refresh project on change of code, and add this script into your editor folder:

using UnityEngine;
using UnityEditor;

public class CustomEditorHelper : MonoBehaviour
{

[UnityEditor.Callbacks.DidReloadScripts]
private static void OnScriptsCompiled()
{
if (!Application.isPlaying)// && EnterPlaymodeAfterCompile)
{

EditorApplication.EnterPlaymode();
}
}

}


When I change code and alt -tab to editor, it doesn’t wait for compile, great!

When I hit ctrl+r to refresh, it refreshes and launches, great!

What it does not mimic of play/stop is:

  1. Does not mimic stop play.

  2. Does not allow launching the game with ctrl+r unless I change code.


My question: I believe I need to know the System Keyword for determining when a hotkey is pressed or when refresh is pressed, not just when processed. Anyone know this? If I knew when refresh hotkey was pressed, I could check if game running → stop. Or if code compiled → run anyway

OId code snippets on google do not get hotkey presses in editor, and This documentation doesn’t help either: Namespace UnityEditor

This is probably late, but I’ll leave it here anyway. I’ve faced the same issue but fixed it from other side: I’m refreshing asset database if it’s changed upon entering play mode. The trickiest part is detecting changes in scripts. As far as i know, Unity doesn’t have any methods to check if database has changed, so I’m using C# class FileSystemWatcher. This is my fix, it goes to Assets/Editor folder.

using UnityEngine;
using UnityEditor;
using System.IO;

[InitializeOnLoad]
public class AutoRefresher
{
    private static FileSystemWatcher watcher;
    private static bool doReload = false;
    static AutoRefresher()
    {
// FileSystemWatcher needs to be disposed after its work is done, so we disposing it before assembly reloads 
        AssemblyReloadEvents.beforeAssemblyReload += CleanUp;
        EditorApplication.playModeStateChanged += OnPlayModeChanged;

// settings for FileSystemWatcher, making shure it is capturing all changes in script files
        watcher = new FileSystemWatcher(Path.GetFullPath(Application.dataPath));
        watcher.Filter = "*.cs";
        watcher.Changed += OnAssetsChanged;
        watcher.Created += OnAssetsChanged;
        watcher.Deleted += OnAssetsChanged;
        watcher.Renamed += OnAssetsChanged;
        watcher.IncludeSubdirectories = true;
        watcher.EnableRaisingEvents = true;
    }

    private static void OnAssetsChanged(object sender, FileSystemEventArgs e)
    {
// if any script was changed then database should be reloaded before entering play mode
        doReload = true;
    }

    private static void OnPlayModeChanged(PlayModeStateChange state)
    {
        switch (state)
        {
            case PlayModeStateChange.ExitingEditMode:
                OnPlayModeEntered();
                break;
        }
    }

    private static void CleanUp()
    {
        if (watcher != null)
            watcher.Dispose();
    }

    private static void OnPlayModeEntered()
    {
        if (doReload)
        {
            Debug.Log("asset database refresh");
            doReload = false;
            AssetDatabase.Refresh();
        }
    }
}
4 Likes

TY. I have one that works: f11 or f12 launches/stops it

using System;
using System.IO;
using System.Text;
using UnityEngine.SceneManagement;
using UnityEngine;
using UnityEditor;
using UnityEngine.Events;
using UnityEngine.Scripting;
using UnityEditorInternal;
using UnityEditor.Scripting;
using UnityEngine.TestTools;
using Unity.Profiling;
using UnityEditor.Profiling;
using UnityEditor.SceneManagement;
using UnityEditor.VersionControl;
using UnityEngine.Profiling;
using System.Reflection;

public static class GlobalKeyEvents
{
// Exposed delegates to hook up your methods to them.
public static event Action<KeyCode, EventModifiers> GlobalKeyDown;
public static event Action<KeyCode, EventModifiers> GlobalKeyUp;
public static event Action AnyShortcutTriggered;

[InitializeOnLoadMethod]
private static void EditorInit()
{
RegisterToGlobalEventHandler();
RegisterToTriggeredAnyShortcut();
}

private static bool OnAnyShortcutTriggered()
{
AnyShortcutTriggered?.Invoke();
return true;
}

private static void RegisterToGlobalEventHandler()
{
FieldInfo info = typeof(EditorApplication).GetField(“globalEventHandler”, BindingFlags.Static | BindingFlags.NonPublic);
EditorApplication.CallbackFunction value = (EditorApplication.CallbackFunction)info.GetValue(null);
value += OnGlobalKeyPressed;
info.SetValue(null, value);
}

private static void RegisterToTriggeredAnyShortcut()
{
FieldInfo info = typeof(EditorApplication).GetField(“doPressedKeysTriggerAnyShortcut”, BindingFlags.Static | BindingFlags.NonPublic);
Func value = (Func)info.GetValue(null);
value += OnAnyShortcutTriggered;
info.SetValue(null, value);
}

private static void OnGlobalKeyPressed()
{

if (Event.current.type == EventType.KeyDown)
{

KeyCode key1 = Event.current.keyCode;

switch (key1)
{
case KeyCode.W:
//Debug.Log(“W!”);
break;
case KeyCode.F11:
case KeyCode.F12:
{

if (Application.isPlaying)
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;

#endif

}
else
{
UnityEditor.AssetDatabase.Refresh();
UnityEditor.EditorApplication.EnterPlaymode();
}

}
break;

}

GlobalKeyDown?.Invoke(Event.current.keyCode, Event.current.modifiers);
}
else if (Event.current.type == EventType.KeyUp)
{
GlobalKeyUp?.Invoke(Event.current.keyCode, Event.current.modifiers);
}
}
}

It’s dumb Unity hasn’t had this by default for the past 8 years. Nothing is lost using it and an hour of dev is gained for every 8 hours devved… It’s straight brain dead UNITY CEOs haven’t cleaned this up yet.