Symptoms:
- I don't always want Unity to reload my script assemblies.
- Recompiling script files during play mode is causing problems.
Cause:
Unity will recompile any changes to script files as soon as the changes are imported.
Resolution:
You can change this behavior by going to Edit > Preferences > General and disabling Auto Refresh.
Alternatively, click the drop-down to the right of Script Changes While Playing and click either, Recompile After Finished Playing or Stop Playing And Recompile.
If you disable Auto Refresh, you need to refresh the project after each script change manually. You can do this by pressing Crtl+R on Windows or ⌘+R on Mac.
Another option is to change this behavior with a script. You can use one of the following code examples:
This example adds a menu to the menu bar. It works like a shortcut to the settings mentioned before.
using UnityEditor; public class ScriptOptions { //Auto Refresh //kAutoRefresh has two posible values //0 = Auto Refresh Disabled //1 = Auto Refresh Enabled //This is called when you click on the 'Tools/Auto Refresh' and toggles its value [MenuItem("Tools/Auto Refresh")] static void AutoRefreshToggle() { var status = EditorPrefs.GetInt("kAutoRefresh"); if(status == 1) EditorPrefs.SetInt("kAutoRefresh",0); else EditorPrefs.SetInt("kAutoRefresh", 1); } //This is called before 'Tools/Auto Refresh' is shown to check the current value //of kAutoRefresh and update the checkmark [MenuItem("Tools/Auto Refresh", true)] static bool AutoRefreshToggleValidation() { var status = EditorPrefs.GetInt("kAutoRefresh"); if(status == 1) Menu.SetChecked("Tools/Auto Refresh",true); else Menu.SetChecked("Tools/Auto Refresh", false); return true; } //Script Compilation During Play //ScriptCompilationDuringPlay has three posible values //0 = Recompile And Continue Playing //1 = Recompile After Finished Playing //2 = Stop Playing And Recompile //The following methods assing the three possible values to ScriptCompilationDuringPlay //depending on the option you selected [MenuItem("Tools/Script Compilation During Play/Recompile And Continue Playing")] static void ScriptCompilationToggleOption0() { EditorPrefs.SetInt("ScriptCompilationDuringPlay", 0); } [MenuItem("Tools/Script Compilation During Play/Recompile After Finished Playing")] static void ScriptCompilationToggleOption1() { EditorPrefs.SetInt("ScriptCompilationDuringPlay", 1); } [MenuItem("Tools/Script Compilation During Play/Stop Playing And Recompile")] static void ScriptCompilationToggleOption2() { EditorPrefs.SetInt("ScriptCompilationDuringPlay", 2); } //This is called before 'Tools/Script Compilation During Play/Recompile And Continue Playing' //is shown to check for the current value of ScriptCompilationDuringPlay and update the checkmark [MenuItem("Tools/Script Compilation During Play/Recompile And Continue Playing", true)] static bool ScriptCompilationValidation() { //Here, we uncheck all options before we show them Menu.SetChecked("Tools/Script Compilation During Play/Recompile And Continue Playing", false); Menu.SetChecked("Tools/Script Compilation During Play/Recompile After Finished Playing", false); Menu.SetChecked("Tools/Script Compilation During Play/Stop Playing And Recompile", false); var status = EditorPrefs.GetInt("ScriptCompilationDuringPlay"); //Here, we put the checkmark on the current value of ScriptCompilationDuringPlay switch (status) { case 0: Menu.SetChecked("Tools/Script Compilation During Play/Recompile And Continue Playing",true); break; case 1: Menu.SetChecked("Tools/Script Compilation During Play/Recompile After Finished Playing", true); break; case 2: Menu.SetChecked("Tools/Script Compilation During Play/Stop Playing And Recompile", true); break; } return tr
You should see these options on the menu bar.

This other example directly blocks script compilation while in play mode.
using UnityEditor; [InitializeOnLoad] public class CompilerOptionsEditorScript { static CompilerOptionsEditorScript() { EditorApplication.playModeStateChanged += PlaymodeChanged; } static void PlaymodeChanged(PlayModeStateChange state) { //Enable assembly reload when leaving play mode/entering edit mode if (state == PlayModeStateChange.ExitingPlayMode || state == PlayModeStateChange.EnteredEditMode) { EditorApplication.UnlockReloadAssemblies(); } //Disable assembly reload when leaving edit mode/entering play mode if (state == PlayModeStateChange.EnteredPlayMode || state == PlayModeStateChange.ExitingEditMode) { EditorApplication.LockReloadAssemblies(); } }
Remember to put the script you choose inside a folder called Editor inside your Assets folder.
More Information:
Comments
7 comments
This worked perfectly. Much appreciated.
FYI, since Unity 2017.2, these warnings for lines 21, 33 make the above editor script ineffective as-is:
Assets/Editor/CompilerOptionsEditorScript.cs(33,27): warning CS0618: `UnityEditor.EditorApplication.playmodeStateChanged' is obsolete: `Use EditorApplication.playModeStateChanged and/or EditorApplication.pauseStateChanged'
Assets/Editor/CompilerOptionsEditorScript.cs(33,27): warning CS0618: `UnityEditor.EditorApplication.playmodeStateChanged' is obsolete: `Use EditorApplication.playModeStateChanged and/or EditorApplication.pauseStateChanged'
Per suggestion, fixing the capitalisation from
playmodeStateChanged
to
playModeStateChanged
https://docs.unity3d.com/2017.2/Documentation/ScriptReference/EditorApplication-playModeStateChanged.html
gets a different new error:
Assets/Editor/CompilerOptionsEditorScript.cs(33,27): error CS0123: A method or delegate `CompilerOptionsEditorScript.PlaymodeChanged()' parameters do not match delegate `System.Action<UnityEditor.PlayModeStateChange>(UnityEditor.PlayModeStateChange)' parameters
which appears related to the issue noted here:
https://github.com/dotBunny/VSCode/issues/162
and as some current doc illustrates,
https://docs.unity3d.com/ScriptReference/EditorApplication-playModeStateChanged.html
The new function takes one parameter, so the delegate method in the above editor script needs to be updated with a valid matching parameter, e.g.
static void PlaymodeChanged(PlayModeStateChange state)
however the delegate method does not currently do anything with that state variable, and in some circumstances the following line:
if( EditorApplication.isPlaying )
can be replaced with something like:
if (state==PlayModeStateChange.EnteredPlayMode)
but it will probably work as-is.
Refer to the doc on the exact meaning of those state enumerations:
https://docs.unity3d.com/ScriptReference/PlayModeStateChange.html
The old function name will work up to and including 2017.1
https://docs.unity3d.com/2017.1/Documentation/ScriptReference/EditorApplication-playmodeStateChanged.html
As of (at least, Unity doesn't pay me to QA) 2021.1.5f1, this no longer works (even with the proposed changes to get around the obsolete warnings). The if condition in OnEditorUpdate is never hit, even if you are in play mode and compiling. The isCompiling flag is never set to true before compilation is triggered and you start the dreaded null reference exception parade.
I was able to get around this by just removing the isCompiling flag (you still get a short "is compiling" popup in unity, but it doesn't seem to go any further
Using Unity 2021.2.19f1, Edit > Preferences > General does not have an Auto Refresh option and the first script in this article is cut off, so I'm unable to test that.
Jake Pollard - Auto Refresh moved here:
Edit -> Preferences -> Asset Pipeline -> Auto Refresh
click the drop-down to the right of Script Changes While Playing and click Recompile After Finished Playing. => Does not work on MacOS (Silicon) with Unity 2021.3.0 (LTS) if you don't check ALSO "Auto Refresh"
If with auto-refresh disabled, your scripts still continue compiling I might have found a solution (in my case). I have spent a few hours trying to figure this out and hopefully this will help someone.
I am using Unity 2022.2 and Unity 2021.3 (LTS) with the latest version at the time of writing this comment.Auto refresh was off but I've seen that 2 different projects had different versions of Burst. And in both cases Burst had the "chain link" icon (installed as a dependency)
The solution in my case was: I reinstalled Burst by name (Packager Manager -> "+" sign -> "Add packager by name.. -> added "com.unity.burst"). Installed version is 1.8.4.This seems to have solved it. Some settings might have been reinitialized.
Please sign in to leave a comment.