- Home /
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.
Same problem here. Unity's live-recompile crashes my code 100%. How could they not have added a disable for this?
Agreed, this is kind of ridiculous. $$anonymous$$y game always crashes on live recompile and I'm not going to add support for it (would be far too hard). There's no reason to make it crash every time though.
You should really make Benakin486's answer the best answer as it actually provides a working solution.
Answer by CapeGuyBen · Jun 23, 2015 at 06:38 AM
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: https://capeguy.co.uk/2015/06/no-more-unity-hot-reload/.
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;
}
Awesome! This is the first answer I've seen that really works. Thanks greatly.
And it only took about 3 years.
I've created an updated script which uses EditorApplication.LockReloadAssemblies() based on this support article and written another post about this: Disabling Assembly Reload While in Play $$anonymous$$ode
The code is here and here:
// Cape Guy, 2018. Use at your own risk.
using UnityEditor;
using UnityEngine;
/// <summary>
/// Prevents script compilation and reload while in play mode.
/// The editor will show a the spinning reload icon if there are unapplied changes but will not actually
/// apply them until playmode is exited.
/// Note: Script compile errors will not be shown while in play mode.
/// Derived from the instructions here:
/// https://support.unity3d.com/hc/en-us/articles/210452343-How-to-stop-automatic-assembly-compilation-from-script
/// </summary>
[InitializeOnLoad]
public class DisableScripReloadInPlay$$anonymous$$ode
{
static DisableScripReloadInPlay$$anonymous$$ode()
{
EditorApplication.play$$anonymous$$odeStateChanged
+= OnPlay$$anonymous$$odeStateChanged;
}
static void OnPlay$$anonymous$$odeStateChanged(Play$$anonymous$$odeStateChange stateChange)
{
switch (stateChange) {
case (Play$$anonymous$$odeStateChange.EnteredPlay$$anonymous$$ode): {
EditorApplication.LockReloadAssemblies();
Debug.Log ("Assembly Reload locked as entering play mode");
break;
}
case (Play$$anonymous$$odeStateChange.ExitingPlay$$anonymous$$ode): {
Debug.Log ("Assembly Reload unlocked as exiting play mode");
EditorApplication.UnlockReloadAssemblies();
break;
}
}
}
}
It happened to me in Unity 2019.4.21f1 LTS that it does not execute the OnEditorUpdate() while compliling. While investigating the issue I read in the docs that "InitializeOnLoad" does in fact fire after recompilation (exactly what we need here). So I reduced this class to just a few lines and it worked like a charm:
using UnityEngine;
using UnityEditor;
/// <summary>
/// This script exits play mode after recompile.
/// </summary>
[InitializeOnLoad] // InitializeOnLoad: Allows you to initialize an Editor class when Unity loads, and when your scripts are recompiled.
public class ExitPlayModeOnScriptCompile
{
static ExitPlayModeOnScriptCompile()
{
if (EditorApplication.isPlaying)
{
Debug.Log("Exiting play mode due to script compilation.");
EditorApplication.isPlaying = false;
}
}
}
Answer by Bunny83 · Jul 19, 2012 at 03:57 AM
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
LockReloadAssemblies doesn't work for me. I just ran it once at startup. Am I doing it wrong?
Answer by Tynan · Sep 07, 2013 at 01:54 AM
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;
}
Just an update: I found that this seems to cause mysterious crashes, so I recommend you don't use it.
I've been using this snippet for a while, I use it because my editor locks up. I haven't had any crashes... however if you are using it during a game loop like Update, it will not work when the editor is Playing, but also Paused, and also compiling...
So I suggest you move it to something like OnDrawGizmos, which is always being called: Bonus: You don't need the #if Editor part because Gizmos only runs while in editor mode!
void OnDrawGizmos() {
if (UnityEditor.EditorApplication.isCompiling &&
(UnityEditor.EditorApplication.isPlaying || UnityEditor.EditorApplication.isPaused)) {
Debug.Log("Compiled during play; automatically quit.");
UnityEditor.EditorApplication.Beep();
UnityEditor.EditorApplication.isPlaying = false;
}
}
Unrelated: Hey!!! $$anonymous$$aker of Rim world. I just got done with a 3day binge on the game. $$anonymous$$y suggestion: $$anonymous$$ountable animals for speed, other types of animals or space aliens that have intelligence, and try to make starting weapons more necessary like bows and swords! early game seems to not play a big role.
Answer by yoyo · May 20, 2014 at 09:38 PM
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.
Tried to use this on Unity 4.5 but the Suspend causes the game to pause and editor UI to stop responding (apart from the menu bar) until I Resume again.
Answer by Antony-Blackett · Nov 20, 2014 at 11:37 PM
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
}