Can I disable live recompile?

Unity’s ability to rebuild (recompile) script files that change while running is impressive; however due to various limitations with that feature, my current project can’t run after a live recompile.

I wonder if I could disable this behavior in my project? I’d like to be able to tweak code files and save them without switching back to my game and find that I need to restart.

Here’s the script I wrote to solve this problem (similar to what Tynan suggests above). I wrote a blog post on the subject here: No More Unity Hot-Reload – Cape Guy.

The basic idea is to get the editor to automatically detect a script recompile while in play mode and immediately exit play mode (before any hot-reloading has chance to happen). As hot-reloading requires you to not use any types which can’t be serialised (such as Dictionaries), and has a few other limitations, I don’t think it’s that useful anyway so don’t really miss it.

Anyway, here’s the code for anyone who’s interested:

Editor/ExitPlayModeOnCompile.cs

// Cape Guy, 2015. Use at your own risk.

using UnityEngine;
using UnityEditor;

/// <summary>
/// This script exits play mode whenever script compilation is detected during an editor update.
/// </summary>
[InitializeOnLoad] // Make static initialiser be called as soon as the scripts are initialised in the editor (rather than just in play mode).
public class ExitPlayModeOnScriptCompile {
	
	// Static initialiser called by Unity Editor whenever scripts are loaded (editor or play mode)
	static ExitPlayModeOnScriptCompile () {
		Unused (_instance);
		_instance = new ExitPlayModeOnScriptCompile ();
	}

	private ExitPlayModeOnScriptCompile () {
		EditorApplication.update += OnEditorUpdate;
	}
	
	~ExitPlayModeOnScriptCompile () {
		EditorApplication.update -= OnEditorUpdate;
		// Silence the unused variable warning with an if.
		_instance = null;
	}
	
	// Called each time the editor updates.
	private static void OnEditorUpdate () {
		if (EditorApplication.isPlaying && EditorApplication.isCompiling) {
			Debug.Log ("Exiting play mode due to script compilation.");
			EditorApplication.isPlaying = false;
		}
	}

	// Used to silence the 'is assigned by its value is never used' warning for _instance.
	private static void Unused<T> (T unusedVariable) {}

	private static ExitPlayModeOnScriptCompile _instance = null;
}

I never tried those two function, but they might help:

Those are of course editor functions and belong to the UnityEditor namespace. So use them in editor scripts or if you use them in runtime scripts, make sure you suround them with #if UNITY_EDITOR #endif:

#if UNITY_EDITOR
UnityEditor.EditorApplication.LockReloadAssemblies();
#endif

I couldn’t stop it from compiling, but this ugly little snippet (run in an Update) made it at least quit gracefully when that happened.

if(EditorApplication.isCompiling)
{
    	Debug.Log("Compiled during play; automatically quit.");
    	EditorApplication.Beep();
    	EditorApplication.isPlaying = false;
}

You can use the AssetDatabase to suspend and resume the import of all assets, including the recompilation of modified code. This will turn off live recompile, as requested, but also turns off all other asset importing, which may not suit your needs.

This editor script adds two menu items to the Assets menu to suspend and resume importing.

using UnityEditor;

public static class AssetImportSuspendResume
{
    [MenuItem("Assets/Suspend Importing")]
    public static void Suspend()
    {
        AssetDatabase.StartAssetEditing();
    }
    
    [MenuItem("Assets/Resume Importing")]
    public static void Resume()
    {
        AssetDatabase.StopAssetEditing();
        AssetDatabase.Refresh();
    }
}

P.S. I also tried LockReloadAssemblies. It sounded promising, but I couldn’t get it to affect the behaviour of live compilation.

Here’s a script I just wrote, it seems to work. The only quirk is the little compile spinner is present at the bottom of Unity from the start of recompilation until you stop play mode.

This script will also start the compile again when you stop playmode so you don’t have to manually initiate a recompile.

Just drop this script onto a object in your starting scene. Note that this script sets that object DontDestroyOnLoad(), it’s also a singleton so it can be in multiple scenes without issue but it will kill its gameObject if another already exists, including all the other scripts on it so you may want to give it its own GameObject (this hasn’t really been tested though as my game only has 1 scene right now).

using UnityEngine;
using System.Collections;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class StopLiveCompile : MonoBehaviour 
{
#if UNITY_EDITOR
	static StopLiveCompile instance;

	bool locked = false;
	void Awake()
	{
		if( instance != null )
		{
			Destroy( gameObject );
		}
		else
		{
			instance = this;
			locked = false;
			EditorApplication.playmodeStateChanged += HandleOnPlayModeChanged;
			DontDestroyOnLoad( gameObject );
		}
	}
	
	void HandleOnPlayModeChanged()
	{
		if (!EditorApplication.isPlaying)
		{
			EditorApplication.playmodeStateChanged -= HandleOnPlayModeChanged;
			if( locked )
			{
				EditorApplication.UnlockReloadAssemblies();
				AssetDatabase.Refresh();
			}
		}
	}

	void Update()
	{ 
		if( EditorApplication.isCompiling && !locked )
		{
			locked = true;
			EditorApplication.LockReloadAssemblies();
		}
	}
#endif
}

I like Benakin486’s solution, but I wanted to mention my tool which offers other ways of dealing with this issue. Benakin486’s solution will stop your app immediately and that will prevent live recompile. I think that’s great for certain situations. My tool can postpone compilation until you press stop, so your play session is not interrupted…which is good for other situations.

http://unityconsole.com/blog/disable-unity-live-recompile

I’ve found Unity source code on GitHub Unity-Technologies/UnityCsReference and in particular this script: Editor/Mono/PreferencesWindow/PreferencesWindow.cs

Here is the line that responsible for Editor’s Auto Refresh (which located in Edit → Preferences → General → Auto Refresh checkbox):

EditorPrefs.SetBool("kAutoRefresh", m_AutoRefresh);

By changing “m_AutoRefresh” variable you can switch auto compiling via code, if needed

Unless I’m missing something, Edit->Preferences->General->Script Changes While Playing. Options are -Recompile and continue playing, -Recompile after finished playing, -Stop playing and recompile.

As far as I’m aware there is no way to disable unity’s recompile when scripts change without some nasty code reflection. It’s a necessary step to ensure games run correctly. If you can’t run your game with it on, then there’s definitely a better way to do what your doing. Can you post the code that your trying to run?

Since Unity 2018.2 you can go to Preferences → General → Script Changes While Playing and select the expected behavior to be executed when re-compiling scripts while on playmode.