Symptoms
- I do not 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
Unity provides a method for preventing the script assemblies from being loaded.
Firstly, create an Editor Script that will be loaded at while the project is open with [InitializeOnLoad], and receive update events from the Editor with the EditorApplication.update delegate.
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class CompilerOptionsEditorScript
{
static CompilerOptionsEditorScript()
{
EditorApplication.update += OnEditorUpdate;
}
static void OnEditorUpdate()
{
if( EditorApplication.isCompiling )
Debug.Log( "Scripts are compiling" );
}
}
When EditorApplication.isCompiling is detected, use EditorApplication.LockReloadAssemblies() where needed to prevent Unity from compiling the scripts until EditorApplication.UnlockReloadAssemblies() is called.
To prevent scripts recompiling during PlayMode, EditorApplication.isPlaying can be used to detect if the Editor is in PlayMode; and the EditorApplication.playmodeStateChange event for changes to the state.
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class CompilerOptionsEditorScript
{
static bool waitingForStop = false;
static CompilerOptionsEditorScript()
{
EditorApplication.update += OnEditorUpdate;
}
static void OnEditorUpdate()
{
if( ! waitingForStop
&& EditorApplication.isCompiling
&& EditorApplication.isPlaying )
{
EditorApplication.LockReloadAssemblies();
EditorApplication.playmodeStateChanged
+= PlaymodeChanged;
waitingForStop = true;
}
}
static void PlaymodeChanged()
{
if( EditorApplication.isPlaying )
return;
EditorApplication.UnlockReloadAssemblies();
EditorApplication.playmodeStateChanged
-= PlaymodeChanged;
waitingForStop = false;
}
}
More Information
http://docs.unity3d.com/Manual/RunningEditorCodeOnLaunch.html
http://docs.unity3d.com/ScriptReference/EditorApplication.html
Comments
2 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
Please sign in to leave a comment.