/Editor Scripts Organization with 2017.3 Assembly Definition Files
After experiencing great success with the new asmdef build organization system on a small test project, I am now in the middle of converting a larger project to use asmdef files as well. This project contains a number of third-party libraries, which are all organized as children of the project's root /Plugins folder. Each of these third-party libraries contains at least one Editor scripts folder, the contents of which are (of course) dependant on non-editor scripts. Edit scripts can also (of course) not be included in published builds since they reference the UnityEditor namespace.
I have been creating a separate asmdef file for each third-party library, and another asmdef file for each editor folder inside each library. This has proven to be more complicated than I had anticipated, with libraries such as Awesome Technologies' Vegetation Studio (as one example) containing half a dozen self-referential editor folders at different locations in it's organizational hierarchy.
Plot twist: A number of third-party libraries have cyclical Editor script dependencies.
In the pre-asmdef world, this was a very simple problem. All "Editor" folders were automatically assigned to first script compilation pass, and wound up in the same assembly. I expected to solve this in the post-asmdef world by creating two identical asmdef files in different Editor directories, but this results in the following error: "Assembly with name 'EditorPlugins' already exists (Assets/Plugins/Editor/EditorPlugins.asmdef)"
I am preparing to restructure all the third-party libraries in this project, moving all their editor scripts into a single folder hierarchy that can be bundled into a single assembly using a top-level asmdef file. This feels like a code smell, as it will involve maintaining this arbitrary structure in the face of every new library that is installed and updated from now on.
Has anyone else run into this, and hopefully found a better solution? A similar question was asked four days ago, but it didn't touch on cyclical dependencies between multiple editor script directories: https://answers.unity.com/questions/1446378/assembly-definition-in-editor-folder.html
Update: After consolidating all the Editor folders in my project, asmdef-organized builds are now functional. It is still far from clear whether this is a "best-practices" approach.
Have you already filed this as a bug report? I'm in the middle of the process, and at least, so far, I haven't run into any cyclical dependencies ... but I ran into another issue: Each assembly definition file creates its own project in the solution, which results in Visual Studio taking forever to start up (or at least, Reloading the Solution seems extremely slow now, which happens each time there is any change in the folder structure; new files added and so forth).
I believe this is very bad design and should be changed. I noticed the issue when my first build using the new structure failed.
Simply keeping the "whatever is in Editor folders is ignored when making an an actual build" also when using assembly files, and throwing everything in any Editor-folder into one single assembly would be the much better approach. One could still add non Editor folders using the "Include Platforms / Only Editor" approach.
Hi Jashan! I have not personally reported this as a bug, but please do and let us know what feedback you receive from Unity. Several months into implementing the asmdef pattern in all my projects, it's still not clear to me that I have gained anything other than the headaches and lost time of having to manually reorganize every vendor library I import.
I am experiencing exactly the same issues and came up with the same solution. I feel just as bad doing it. I would rather just give up assembly definition files alltogether, but the Test runner with his Play$$anonymous$$ode tests seems to require it in Unity 2018. Anybody figured out how to run play mode tests without assembly definition files?
Answer by jacob_unity652 · Feb 02, 2018 at 02:17 PM
We've got the same problem, our solution was the eventual conclusion you came to, move all the editor scripts into a seperate assembly :(
Another option is to actually keep the editor scripts inside of the non editor assemblies, but surround every editor code file with #IF UNITY_EDITOR and #endif, but that's a pain.
The nice solution would be to put an asmdef into each editor folder that's got the same assembly name, but sadly you can't.
It's unfortunate that Unity can't add the conditional compilation directives automatically for scripts in editor folders. Including the 30 secs to 1 $$anonymous$$ute that Unity froze while rebuilding my project each time I moved or renamed a script, this reorg took all day for just one project.
Damnit. Using the #if UNITY_EDITOR macro was something I used a lot before switching to Assembly Definition. When they released it, they specifically said a downside of it was that you can't use pre-processor macros, that this wouldn't work anymore. But apparently it does, after I already spent a bunch of time separate bundled editor code into their own editor assemblies -_-
There must be a reason why they recommend against it...
@Aubrey-Falconer It wouldn't be as simple as adding those directives to scripts in the editor folder. It would have to look for all references to those editor scripts, and anything using those references and wrap them in the conditional as well, which would greatly increase compilation work. The point of assembly definitions is to help speed up compilation time, and it enforces proper code practices in the way it behaves.
If you have a cyclic reference between editor and runtime code, then that indicates a problem with your approach to the code. Editor code should only see runtime code, runtime code should not be seeing editor code. No spaghetti.
Concerning the cyclic dependencies: These can be between editor scripts in different folders. While of course, production code should never reference editor scripts, editor scripts may very well reference each other and I know quite as few packages where this is the case. The only solution seems to be to restructure the hierarchy so that all editor scripts that reference each other are in the same assembly.
Answer by Whatever560 · May 16, 2018 at 12:48 PM
Our dirty trick that also handles circular deps, move everything in a 3rdPartiesEditor folder and keeping the hierarchy. It's very quick to do.
Very easy to rollback: just copy everything back where your store your 3rd parties
Create all subdirs
find * -depth -name "Editor" | xargs -I{} sh -c "mkdir --parents \"./3rdPartiesEditor/{}\""
Move all files in 3rdPartiesEditor
find * -depth -name "Editor" | xargs -I{} sh -c "mv \"./{}\"/* \"./3rdPartiesEditor/{}\""
Meta files
find * -depth -name "Editor.meta" | xargs -I{} sh -c "mv \"./{}\" \"./3rdPartiesEditor/{}\""
Create Asmdef file. You might need to adjust references depending on your project. We have a global 3rdparties asmdef for runtime scripts and postprocessing stack V2 (on which cinemachine relies)
{ "name": "ThirdParties.Editor", "references": [ "com.unity.postprocessing.Editor", "com.unity.postprocessing.Runtime", "ThirdParties.Main ], "includePlatforms": [ "Editor" ], "excludePlatforms": [] }
Now it should build !
We are having exactly the same issue when trying to bundle our game.
We made an hopeful guess that all our 3rd parties could be packed into a single .asmdef, though as you say Editor folders are no longer compiled in a separate .dll and thus it seems you need to create every asmdef files manually ... its a very painfull process.
Did you guys find any automated way to handle this ? We have quite a load of scripts ...
There might be a way to do this with a custom build script ?
There is the package manager in 2018 version. It seems to handle compiling packages into its own assembly automatically
I thought the Unity 2018 package manager only handles Unity-own packages, not custom .unitypackage packages. Did I get something wrong? Where is your info from?
We're working on a final game so we're not switching to an unstable 2018 version.
I'll be releasing a tiny plugin on the asset store in the next couple days that modifies the compilation pipeline to exclude the editor files during build.
$$anonymous$$y apologies, I got swamped at work, crunch time and had to step away from it. I'll try and get it all cleaned up and ready this week. I wanted to include some extra features for AS$$anonymous$$Def management.
Your answer
Follow this Question
Related Questions
Change assembly name 4 Answers
Adding additional C# scripts after build (Android, iOS) 1 Answer
Problem with TextMesh Pro when running a build of the game - how to get the right text? 0 Answers
Why am I getting this strange behaviour? 1 Answer
Editor script: Variable created on gameObject in editor set to missing on runtime 0 Answers