Remove UNITY_EDITOR define even for in-Editor builds?

I would like to be able to incrementally build the code in Library\ScriptAssemblies (such as Assembly-CSharp-firstpass.dll) without the UNITY_EDITOR #define. Is this possible?

(Ideally I’d keep my current workflow, which is pressing Ctrl+R in the Unity Editor to incrementally build this code)

Background:

While my question might seem counterintuitive, building Library\ScriptAssemblies without the UNITY_EDITOR #define would allow me to copy over the .dll’s in Library\ScriptAssemblies to a standalone .exe’s Managed directory (since the Managed directory’s .dll’s never has UNITY_EDITOR defined, I need to remove it from Library\ScriptAssemblies to have code compatibility).

I suspect this would allow me to build the standalone .exe once as a Published Build (which, assets and everything, takes close to 1 minute on my machine), and then apply each code change in about 4 seconds – a tremendous iteration time improvement.

This is necessary because our game is multiplayer, and I typically need to launch 2 or 3 instances of the game to test it – and this can only be done with a standalone build.

I’m basically trying to solve the problem detailed here:

I’m not sure if there’s a way to remove Unity’s defines, but you could use player settings to provide your own:

Edit > Project Settings > Player > Other Settings > Configuration > Scripting Define Symbols

Those symbols are defined when compiling, including compiling in the editor. Maybe you could strategically provide (or remove) a define that your code interprets as similar to UNITY_EDITOR, with the exception that you control it? Not an ideal solution, but it’s the first thing that comes to mind.

I haven’t tried swapping out the compiled DLLs that ship with a built player. Curious to hear if it works!

For the last few weeks or so, we’ve been copying the following editor-compiled dll’s to the built player to achieve much faster code iteration:

  • Library/ScriptAssemblies/Assembly-CSharp.dll to Managed/Assembly-CSharp.dll

  • Library/ScriptAssemblies/Assembly-CSharp.dll.mdb to Managed/Assembly-CSharp.dll.mdb

Since none of our game code ends up in Assembly-CSharp-firstpass.* or any of the other .dll’s, this has worked perfectly for game-code-only changes. (Of course changing *.prefab’s or anything outside of game code still requires the execution of a [ten times slower] Published Build)

In order to make this work, I replaced every occurrence of UNITY_EDITOR with:

#if SHIPPING_NOT
if(Application.isEditor)
{ 
    //UNITY_EDITOR code
}
else
#endif//SHIPPING_NOT
{
    //non-UNITY_EDITOR code
}

SHIPPING_NOT is #define’d for development builds, but not player-facing shipping builds.

While I made this replacement for every occurrence of UNITY_EDITOR in the project, this may have been necessary only for the code that compiles into Assembly-CSharp.dll.

My new coding workflow now involves building the standalone .exe once as a Published Build, and then applying each code change with Ctrl+R followed by Ctrl+T (which I’ve mapped to copying Assembly-CSharp.dll and Assembly-CSharp.dll.mdb).

Other notes:

  • copying over every .dll and .dll.mdb did not work – doing so caused the game to crash very early in execution. I didn’t investigate further, having solved my iteration time problem
  • of course sometimes the “straightforward” UNITY_EDITOR replacement needs to be complicated by the code’s conditional compilation logic to avoid inadvertently changing functionality