Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Assembly Definition Woes

Discussion in 'Editor & General Support' started by Wahooney, Dec 20, 2017.

  1. mcroswell

    mcroswell

    Joined:
    Jan 6, 2010
    Posts:
    79
    Thank you all (Kamyker, MNNoxMortem, Karl Jones and Alexees) for helping me understand explicit Assembly manipulation and why you'd do it.

    For others, still in the learning curve for this topic, you might want to check out the "Premier Learning" that is free for the next three months. NOTE: Personally, I feel the Unity Docs should "come up" to this level, but just my opinion.

    Anyway, here's the link on the tutorial for Assembly Definitions:
    https://learn.unity.com/tutorial/working-with-assembly-definitions#5e258435edbc2a0021629372
     
    MNNoxMortem, karl_jones and Kamyker like this.
  2. YJack

    YJack

    Joined:
    Apr 7, 2010
    Posts:
    44
    I'm adding some Assembly Definition in my project. I have a utility folder that includes some extension methods. I've created a "Utility" assembly into that folder, however, looks that other assemblies do not recognize those extension methods, even after I add this "Utility" reference into their own assemblies. What I'm missing something here?
     
  3. Deleted User

    Deleted User

    Guest

    You also need to import their namespace and the Assembly needs to include the platform you're on.
     
  4. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    1,085
    :)
     
    MNNoxMortem likes this.
  5. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    @Kamyker thank you very much for quoting me. Would have missed that post and this way got a notification. Super kind <3.
     
    Kamyker likes this.
  6. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    @karl_jones I have a question regarding code editor opening times and asmdefs. The opening time seems to still scale linearily with number of asmdefs, to the point that any medium-sized project with a couple of packages has > 100 .csproj files, and takes 2-5 minutes to fully load in VSCode / Visual Studio / Rider (that's not "time until I can change code" but "time until Intellisense or equivalent works"). Removing all asmdefs brings the time down to mere seconds.

    Is there coordination / cooperation between the AsmDef team and those teams to improve that situation? Paired with all the ways .csproj files break / are not correct (e.g. creating scripts, renaming asmdefs, adding packages, renaming scripts ,...) which all require "Regenerate C#" followed by a full reopen this is still a painfully slow workflow.
     
  7. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Im not aware of what the teams are doing for this. You can solve this now by not generating a csproj for every asmdef.
    Convert some of your asmdefs into Packages and only include the ones you are currently working on in the project.
    The Visual Studio package gives control over what to generate a csproj for:
    upload_2020-6-24_11-43-24.png
     
  8. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    Hmm, no, the point is that I need all of those. I know there's control for this (I fought hard to have this control and to have all code there).

    Would be great if you could sync with the other teams or point me to the right people, as this is an issue that has arisen from asmdefs and hasn't existed before.
     
  9. Deleted User

    Deleted User

    Guest

    Did not know this exist.
    For me, all boxes where unchecked, but when I then click "Regenerate Project Files", all the csproj files and 1 sln file are back. Am I misunderstanding something?
     
  10. Deleted User

    Deleted User

    Guest

    Rider package has the same control over project generation for packages. However, even when projects are not generated, Rider still allows navigation and editing packages code.
     
  11. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    The issue is not that "editing code text" isn't working, it's that the resulting csproj files are incorrect / missing references and thus don't support Intellisense, Omnisharp, Autocompletion etc.
     
  12. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    @karl_jones who are the right people to talk to? Opening a package-heavy project in VSCode, Rider, VS takes 5-10 minutes by now.
     
    MNNoxMortem likes this.
  13. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Could you please file a bug report?
     
  14. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    @karl_jones here you go: Case 1263386

    Please note that this is simple to reproduce, just try to open any script in any project and count the seconds until Intellisense/Omnisharp/... is ready... same slow in Rider, VSCode, Visual Studio. I understand it will be easy for Unity QA to deflect that and say "that's those IDE makers fault!" but please note that it's a side effect of asmdefs and thus Unity should hopefully be involved in figuring out a way to deal with this.
     
    a436t4ataf, firstuser and karl_jones like this.
  15. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    @karl_jones got another question, hope you don't mind :)

    It seems that every dirty-ing of an asmdef causes a complete recompilation, not just of the relevant parts of the dependency chain. Is that expected? I'd kind of think that "dirty-ing a script in an asmdef" should have the same behaviour as "dirty-ing an asmdef" given that there are 0 actual changes to the asmdef file. This slows down e.g. package updates, because it means that every package update (which necessarily touches asmdef files) has to do a full recompile of everything.

    Is that a bug?
     
  16. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Hmm. It's possible its a bug or it could be that we are recompiling everything to be safe as we may not know what dependencies were changed. Its certainly worth filing a bug report though.
     
  17. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    Reported as
    (Case 1268925) [AsmDef][CompilationPipeline] Reimporting asmdef file without changes does not respect compilation dependencies

    Note that I think I found some pretty hacky stuff with this: In 2020.2.0a19, it seems that the PackMan team has "worked around" this by checking if an asmdef has been changed before marking it dirty on package import, resulting in "compile times as expected". In 2019.4 LTS there's still the full recompile on package change. So I think they "hacked" around the actual underlying issue; whatever the reason the full recompile is in place (bug or not) they're sidestepping it...

    Also, you might be happy to see that it contains an extended and improved version of your AsmDef compile time tracker code ;) Plus I added a UI for it, but still have to clean that up and release it somewhere:

    upload_2020-8-7_13-42-46.png
     
  18. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Nice! I was planning to do something like that but you beat me to it :D
    Im going to share that with the scripting team, it's really useful!
     
    MNNoxMortem likes this.
  19. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    943
    +1 for releasing it, this looks very useful
     
    MNNoxMortem, fherbst and sirxeno like this.
  20. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
  21. Deleted User

    Deleted User

    Guest

    @karl_jones I wanted to ask something since creating scripts of ASMDEF files in our project is getting slower and slower.

    There seems to be a lot of options to manually configure references between assemblies on ASMDEFs. There is also the ability to create ASMDEF references.
    Now my question is, will changing assemblies from auto referencing or being auto referenced change anything compile time related? If so, how?
    The documentation only explains the dependencies and that you can go from auto to manual assignment and all that, but how does that efffect compilation times. Is it worth it?

    Futhermore: Since having more and more ASMDEFs, at least one for each 3rd party package and their editor folder, slows down Visual Studio in opening or refreshing projects, ASMDEF references would be a solution to merge all those into one assembly, since you never touch them. Is that an approach you should take? How could store creators provide this mechanims?

    Thanks for any useful insight on the matter. The slowness of our project is slowly getting on my nerves.
     
  22. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    If possible you should disable "Auto Referenced". It will cause your asmdef to be referenced in predefined assemblies, e,g Assembly-CSharp. This means there's more chance of the asmdef being rebuilt during the compilation of changes to other parts of the project. It does also mean that you will need to add explicit references if you are using it elsewhere. It won't make a difference to the compile-time of an asmdef but it will reduce the number of dependencies which should reduce the overall compilation time when a change is made.

    Assembly definition references can make a big difference. They let you combine code into a single asmdef but keep whatever folder structure you want. I would recommend using them if you can, however, it's very difficult for a 3rd party package provider to use them as they must have a parent asmdef somewhere in the project to function correctly.
    So if you have control over the project then I would go through all the third part stuff and just change them to a small number of asmdefs using asmrefs. It should also help visual studio.

    Its hard to give concrete advice on this as many factors can impact it. A big chunk of time is the assembly reload which is unavoidable. Also if you have any scripts that use InitializeOnLoad then they can sometimes slow things down as they kick in every time a reload occurs.
     
    Deleted User likes this.
  23. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Would you be able to submit a bug for this? The scripting team are planning on focusing on optmizations at the moment and example projects with these issues will help them. It would be interesting to see if this is an asmdef issue or something with visual studio.
    If you could submit some bugs regarding the project issues and general performance then that would help :)
     
  24. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    This last issue (slow IDE load times with increasing number of asmdefs) sounds identical to what I reported a few weeks back as Case 1263386, would be great to get a response. (and it's my post from Jul 15 on this page here)
     
    MNNoxMortem and karl_jones like this.
  25. Deleted User

    Deleted User

    Guest

    @karl_jones Would it be possible to combine ASMDEFs with ASMREFs? In that case 3rd party package provider could provide it and if you wanted to have it different you just applied a "root" ASMDEF from your project. Or would it be possible to add one next to an existing ASMDEF? The issue here is that all solutions seem to require touching and changing the 3rd party package.
     
  26. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    How would that work?
    If you have an asmdef and an asmref in the same directory at the moment this is considered a bug because we don't know which one to pick. Asmrefs require a parent asmdef because there are many other parameters that are required for them to work (dependencies, platforms etc). We cant put those properties into the asmref because then we would get conflicts between the different asmrefs, so there has to be a single parent with the propereties.
    Another issue to consider with this is that using an asmref or falling back to an asmdef could create different types. Any code that may require reflection or require a finding by type (SerializeReference) may find that the type has moved to a different assembly and break. If third party providers start sharing assemblies then there is more chance of type conflicts occuring in those assemblies.
    So there's lots of stuff that can go wrong ;)

    The scripting team are looking into ways to improve this though.
    Moving lots of code into a single dll should not be faster. If anything it should make that dll very slow to compile whereas compiling lots of small dlls in parallel should be faster. So we need to understand why thats not the case. Improve our dependency handling and optimize our assemblies where possible (Unity.Mathmatics).
     
    firstuser likes this.
  27. mergcreations

    mergcreations

    Joined:
    Aug 18, 2020
    Posts:
    1
    Hey, Im a complete newb at all this unity stuff, just trying to build and i believe this is the errors i have been getting and i am not really sure scripting lingo, i followed asset templates, like i said totaly new and this is my first project, ive just been blindly navigating my way through this world haha.

    I can play in edit mode and it just when i try to build i get this

    ArgumentException: The Assembly UnityEditor is referenced by Assembly-CSharp ('Assets/Library/ScriptAssemblies/Assembly-CSharp.dll'). But the dll is not allowed to be included or could not be found.
    UnityEditor.AssemblyHelper.AddReferencedAssembliesRecurse (System.String assemblyPath, System.Collections.Generic.List`1[T] alreadyFoundAssemblies, System.String[] allAssemblyPaths, System.String[] foldersToSearch, System.Collections.Generic.Dictionary`2[TKey,TValue] cache, UnityEditor.BuildTarget target) (at <d1bec46880064709a5e713ad543e6d96>:0)
    UnityEditor.AssemblyHelper.FindAssembliesReferencedBy (System.String[] paths, System.String[] foldersToSearch, UnityEditor.BuildTarget target) (at <d1bec46880064709a5e713ad543e6d96>:0)
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr, Boolean&)

    and it comes with two of these

    Assembly-CSharp.dll to the list of ouptut files in the build report, but a file at that path has already been added.
    and the other is for UnityEngine.UI

    is this the problem thats been conversed about in this thread?

    Ive been able to stumble my way through to this i started with 1000 errors and now down to this so thats kinda cool, but also this is the closest thing finding a solution to it and i am still confused if there is a solution or if this is even what im facing.

    again, not totally sure i understand, but would making a new package with everything in it and disabling the auto reference (or vice versa) and then creating a new project importing the new package allow me to build without these errors?


    thanks. What you all do is amazing, i have mad respect for the coding world
     
    Last edited: Aug 18, 2020
  28. firstuser

    firstuser

    Joined:
    May 5, 2016
    Posts:
    147
    Just FYI for anyone else struggling with time consuming asmdef stuff, this Auto-ASMDEF asset by @Pecek was super useful and saved me a bunch of time getting things working by default.

    My compilation time went down to roughly 1 second (asset reload is what takes the longest now) and I have regained sanity in managing hundreds of asmdef files for third party assets.

    Has some very minor quirks/bugs but even with that I can't imagine going back to manually creating these files unless I absolutely needed to. And the developer has been improving it + went above and beyond with support, especially at the current price.

    I'm a third party with no interests in the asset, just found it to be really useful and wanted to share with others here in case it saves you as much time as it did for me.

    Asset store link: https://assetstore.unity.com/packages/tools/utilities/auto-asmdef-156502

    Forum link: https://forum.unity.com/threads/rel...ject-wide-assembly-definition-creator.769193/
     
    Pecek likes this.
  29. Deleted User

    Deleted User

    Guest

    EDIT: Read the above reponse and it's probably the assembly reload that is taking so long

    @karl_jones I used the compilation visualizer from @fherbst and got this:
    upload_2020-8-19_16-8-40.png

    First of all, why does HoloMRKTEditor, with just one file to compile, take almost 3 times as long as HoloSpaces.dll which has quite a lot more.

    It shows just compiling should take no longer than 4.2 seconds. After hitting Ctrl + R it took about 8 seconds for this window to update and showing about 2 seconds in and it took 27 seconds in total for the Editor to be responsive again (even the spinning wheel is frozen in place).

    Overall there's 171 Assemblies it compiles, a total of roughly 600000 lines of code. Visual Studio says something around 130.

    Do you guys know how to improve that besides compilation, which seems to be quick.
     
    Last edited by a moderator: Aug 20, 2020
  30. Deleted User

    Deleted User

    Guest

    Disabling Auto Refresh does not seem to have any effect when:
    - Adding, changing ASMDEFs/-REFs
    - Creating, moving scripts
     
  31. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,227
    Do you have any scripts with with this https://docs.unity3d.com/ScriptReference/InitializeOnLoadAttribute.html ?
    This runs every time an assembly reload occurs and if the scripts are doing a lot could explain the large amount of time.
     
  32. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    802
    @karl_jones even projects that don't have any user code (only packages) exhibit reload times in the > 10s area, growing at least linearly with assembly count. What time should be expected for reloading a single assembly? 0.01s? 0.1s? 1s?

    Is there a way to analyze what is taking the time there (e.g. breakdown per assembly, or individual steps happening on reload, or OnLoad methods, ...)?

    The Editor log only contains very sparse information about the actual reload (note that this is a "Unity editor is launched" reload, not an actual "after compilation" reload):
    Code (CSharp):
    1. Begin MonoManager ReloadAssembly
    2. Registering precompiled unity dll's ...
    3. Refreshing native plugins compatible for Editor in 0.01 ms, found 0 plugins.
    4. Preloading 0 native plugins for Editor in 0.00 ms.
    5. Invoked RoslynAnalysisRunner static constructor.
    6. RoslynAnalysisRunner will not be running.
    7. RoslynAnalysisRunner has terminated.
    8. Mono: successfully reloaded assembly
    9. - Completed reload, in  12.395 seconds
    It seems that e.g. Burst is able to inject their own timings into the Assembly Reload logs; so somehow there seems to be a way to get and log more info :).
    Code (CSharp):
    1. Burst timings (total:                  985.0ms)
    2.  
    3. UpdateAssemblyCacheDirtyState:           0.0ms
    4. FetchFromAssemblyCache:                  0.0ms
    5. ILCreateModule:                        264.1ms
    6. ILTransform:                            45.3ms
    7. ...
    8. CompileModule:                         153.2ms
    9. CompileToNative:                       505.0ms
    10. ---------------------- -----------------------
    11. Total:                                 985.0ms
    EDIT: Just found https://forum.unity.com/threads/introducing-the-editor-iteration-profiler.908390/ and will take a look, this looks promising.
     
    Last edited: Aug 22, 2020
    MNNoxMortem likes this.
  33. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    646
    One year late to the party. But after reading all this and checking the Profiler & Editor Iteration Profiler, it seems like assembly definitions won't help that much.
    Actual Compile Time is ~3.5s,
    "InitializeOnLoadAttributes" is 3.8s,
    "Restore Managed References" is 2.1s,
    "AwakeScriptedObjects" is 2s,
    "Create and Set Child Domain" is 1s,
    "Post Process all Assets" is 1s,
    Repaint of SceneView, GameView and Inspector is 4.2s
    and 3 seconds of small Stuff.
    (All in all ~21 seconds)

    So the actual compile time isn't that time consuming at all, I was hoping for asmdevs to skip "Restore Managed References" (destroying and recreating existing scripts, which causes a lot garbage) and "InitializeOnLoadAttribute"-calls, as well as reimporting assets.
    But this thread showed that asmdevs won't help with these things.

    So one idea I heard recently, which I want to share here is to have a second project for asset creation. Things like Gaia, ProBuilder, those add up to the iteration time and are only needed to create Objects. We'll probably try moving those to another project and only import finished prefabs (probably using unity packages to keep correct meta files).
    And maybe I'll have to get rid of Odin, as it also shows up almost everywhere in the profiler (InitializeOnLoad, RestoreManagedReferences, redraw Inspector, deserialization callback, ...) :S

    What I don't understand is how the rendering of inspector/sceneView/gameView can take >4 seconds ... I mean, the editor is running at atleast 25fps constantly - so when it is absolutely able to draw those things in milliseconds, why does it take seconds after the recompile?
    Also .. what kind of assets are reimported? I edited a script with 0 references to anything, the monobehaviour is not used anywhere, why would it import anything else than the single script file I changed? No prefab is using this script, no object in any scene .. Would be nice to know which assets are loaded/categorized/scanned/GUID-ed/unloaded in this step.

    Edit: well, seems like the very last part of my post is possible in 2021.2. onwards -> thanks to the Import Activity Window
     
    Last edited: Jul 6, 2021
    Mikael-H likes this.