Follow

How to stop automatic assembly compilation from script

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

Was this article helpful?
2 out of 2 found this helpful
Have more questions? Submit a request

2 Comments

  • 0
    Avatar
    dirk

    This worked perfectly. Much appreciated.

  • 0
    Avatar
    Morte

    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

    Edited by Morte
Please sign in to leave a comment.