Search Unity

Assembly Definition files not working as expected.

Discussion in 'Editor & General Support' started by Lee7, Jan 5, 2018.

  1. deab

    deab

    Joined:
    Aug 11, 2013
    Posts:
    83
    I've made a few attempts to set up an ongoing project that includes a number of assets, and each time given up as I couldn't get past the error messages which I don't find very helpful. A real shame, would love to divide my own code up to reduce compile times.
     
  2. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    202
    What error messages?
     
  3. deab

    deab

    Joined:
    Aug 11, 2013
    Posts:
    83
    Multiple 'The type or namespace name `xxxxx' could not be found. Are you missing an assembly reference?' type errors.

    I just made a fresh attempt on a back up, and I did finally get this to work. This time I created the minimum asmDef files (my scripts, editor, plugins and addins) but I'm not seeing any gains in compile time.

    To attempt compile time gains I tried further splitting my code, but this took me back to 'not found' errors, even when adding references between the new asmDef and the parent.
     
  4. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    202
    @deab Four things I'd like to share that I've learned:
    - If there's any compile time improvements, than it's when changing code in assemblies that are not futher refererenced, because otherwise, referencing assemblies also need to be compiled
    - Even though there might not be any compile time improvements, you're still forced to structure your code without circular dependencies, which is a good thing
    - Speaking of which, there must not be any circular dependencies withing assembly references, otherwise they won't compile anymore and throw that kind of error at the end of the list of errors
    - ATTENTION: At some point it's possible to receive errors even though there's no logical reason for missing references to appear. Restarting the editor helps. If not, deleting the library will.

    - I converted a solution to using them and ended up with about 40 ASMDEFs. It took me about 3 days. Here's what I always did to get it right:
    - Check what the assembly the script, throwing the error, resides in
    - Check what assembly the script, which is missing in the error, resides in
    - Reference the second one to the first
    - If it's not in an assembly, create a new one
    - If there'll be any circular references due to this, one way to resolve it is to create yet another ASMDEF, referenced by both participating assemblies with either the type causing it or an extracted interface moved to.

    Be assured that every not found error can be resolved.
     
  5. deab

    deab

    Joined:
    Aug 11, 2013
    Posts:
    83
    Thanks for the tips @Alexees will make another attempt at some point.
     
  6. mmortall

    mmortall

    Joined:
    Dec 28, 2010
    Posts:
    81
    Alexees, how the compilation time changes?
    I am not able to get it work. It compiles without errors. I have around 6 asmdef files. All my non-dll plugins are under one asmdef. But I get around 17 sec compilation. So I get all recompiled if I change my game code.
     
  7. cnheider

    cnheider

    Joined:
    Apr 5, 2017
    Posts:
    9
    Spent all day doing exactly this...
     
  8. ThinhHB

    ThinhHB

    Joined:
    Oct 24, 2014
    Posts:
    5
    This's exactly what I'm looking for !!! Thanks so much !!
     
    karl_jones likes this.
  9. Wolk

    Wolk

    Joined:
    Jul 12, 2014
    Posts:
    58
    Hey guys, please watch out when using asmdefs! I've tried to implement unit testing in my project, so I put asmdef file in my scripts folder to call that one from the test script, however it didn't find 3rd party dependencies, so i decided to put asmdef file in root (Assets) folder. BIG MISTAKE!
    It worked out nicely, everything compiled and it seemed to work, until i came home. After downloading the project from colab (or basically same as deleting library/meta files), it couldn't compile any script in the scene and so i decided to delete the asmdef from root, everything in my scene became unlinked! Luckily i could rollback, but just watch out when using asmdefs, so it doesn't screw up your project.
     
  10. Oulassoglou

    Oulassoglou

    Joined:
    Apr 10, 2016
    Posts:
    3
    Actually, this is not always the case. In a normal .csproj we would've been able to define an AssemblyInfo.cs and indicate that a project needs to be treated as internal by other projects. See InternalsVisibleTo property.
    Unity just replaces this file on compilation. Was there really a reason to re-invent the wheel?
     
  11. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    Im aware of that. Not sure I follow how it allows multiple projects to be in one project in visual studio though. What are you suggesting?
     
  12. Oulassoglou

    Oulassoglou

    Joined:
    Apr 10, 2016
    Posts:
    3
    Normally, with c# AssemblyInfo.cs files, we can define separate projects as part of an internal namespace. This helps programmers separate their code is separate inter-dependent projects, without exposing the code as public (big nono for security reasons). As far as I am aware this cannot be defined with the current implementation of .asmdef files, so I don't understand the reason behind creating this functionality in the first place, when the same capability, with even more options, exists in the core language itself.
     
  13. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    Scripting team inform me that AssemblyInfo files do work in asmdefs. We actually leverage this ourselves for packages for hiding assembly API that are only internal for the package.
     
  14. Oulassoglou

    Oulassoglou

    Joined:
    Apr 10, 2016
    Posts:
    3
    Please correct me if I'm wrong in the following.

    Yes, AssemblyInfo files work with Unity, but only a single one at a time is currently possible.
    For example, say I have a parent directory 'functiontypes' and, in it, a subdirectory of 'modeltypes' (with its own asmdef file)
    In Visual Studio these two will appear as separate projects and not treated as part of the same namespace.
    I can only have one AssemblyInfo file in the parent directory, defining 'modeltypes' as internal, but I cannot define 'functiontypes' as internal for 'modeltypes', since physically only one AssemblyInfo file can exist, even if they are treated as two separate VS studio projects.

    Edit: Maybe treating the subdirectory as internal might not make perfect sense in this specific example, but the same restriction applies for two separate subdirectories/projects wanting to treat one another as internal.
     
    Last edited: Oct 23, 2018
  15. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    Im not sure I fully understand the problem. Are you able to share an example project that demonstrates the issue?
     
  16. AmitSuri

    AmitSuri

    Joined:
    Sep 26, 2017
    Posts:
    15
    A standard Unity style video would really help explain how to organize a large project using asmdefs.
     
    vovo801 and deab like this.
  17. TeagansDad

    TeagansDad

    Joined:
    Nov 17, 2012
    Posts:
    782
    @karl_jones - I've run into a weird problem recently: Visual Studio will not recognize any types from some assembly definitions.

    The following examples are all from the same Unity 2018.3.0f2 project:

    When using Visual Studio 2015 Community, everything works as expected until I try to reference a type from an assembly definition for a Package (TextMesh Pro, in this case). Visual Studio will not recognize any types contained within the TextMesh Pro assembly. However, it will pick up types contained within the local TMPro examples folder (TMPro.Examples namespace).

    When using Visual Studio 2017 Professional, nothing works regarding asmdefs. Visual Studio won't recognize any types contained within any assembly definition.

    I have removed Visual Studio Tools for Unity and installed the latest version(s) multiple times, I have updated both Visual Studio 2015 and 2017 to their latest versions.

    Everything was working fine in all versions of Unity that I have installed and with both versions of VS (Editor asmdefs are configured correctly, etc). It was after installing Unity 2018.3.0f2 (side-by-side with other versions) that all of this started. Seems like it messed up something with the VS bridge, as my projects in 2018.2.6f1 and 2017.3.1f1 have the same problems.

    Any ideas as to what might be causing this?
     
  18. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    688
    @karl_jones I have the same problem.
     
  19. Enoch

    Enoch

    Joined:
    Mar 19, 2013
    Posts:
    189
    I want to reiterate how much of a nightmare this is. Especially if there are multiple Editor directories and some of those directories contain files that reference other editors with partial classes. In this case I think the only solution is to pull all editor files into a separate directory and compile it with a seperate editor assembly there (actually this probably preferred to having tons of little dlls for every Editor directory).

    The big problem I have is upgrading assets when there is new releases is now a major pain (as if this first step wasn't a pain).

    But now that I think about it. An Editor function might help here. something that did something like this:
    1 Select a directory.
    2 Find all Editor directories under that directory and copy the contents to a new directory (rename copied files and directories that clash on name).
    3. add an assembly to the assets root directory
    4. add an assembly to the new editor directory, add assembly added in step 3 to this editor assemblies references

    And that should upgrade the asset to use assemblies without the cross reference problems. I guess I should probably write this now before this gets more and more out of hand.
     
  20. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    397
    Switching from Non-asmdef projects to asmdef is pretty annoying but once setup it works nice (we have a rather medium-sized project with 120 *.asmdef files and complex references due to some kind of spaghetti architecture).

    What I am annoyed the most is that they do not improve the iteration times but make developement extremly slow. I have no idea what is really going wrong but even a small chain of 4 assemblies looks like it triggers a complete recompilation of all 120 assembly and the IDE (VS17/Rider) completly reloads the project and everything is like one or two magnitudes slower than actually without them (and actually only the affected chain of *.dlls should be recompiled...)

    Also editing the asmdef in the Inspector is painfully slow. I quite often fall back to simply edit the file in a text editor/IDE of my choice... Editing 120 asmdef files is like 1-2 hours if it requires multiple "apply changes" clicks. Ain't nobody got time for that.

    Edit: Rider has asmdef support. No idea about VSTU but I hope they are working on the same features here. What Rider currently does not do properly but what is at least on their radar is to auto-update the asmdef when you directly work in Rider, which will reduce the time to reference one assembly from another inside of the IDE from like a minute to a few seconds.

    I consider it a good one that they do not allow cycles, and unity should enforce asset store plugins with code to be shipped with an *.asmdef (not now, but sooner or later). This in-between two systems is what really is annoying. The author of a plugin should be responsible to setup their plugin.

    A plugin with multiple editor folders is really annoying as there are in many cases cross-dependencies which means you MUST restructure third party code, something you will have to do on any update of the plugin. That I consider highly dangerous, error prone and bad style.

    I recommend to contact the authors to restructure their plugin. Going back for any user is easy: Just delete the provided *.asmdef files if they still use the /Editor folder, but just a single one (or at least setup references correctly if using multiple ones) but going forward is a pain. Also so far most authors of larger plugins had no problem to move forward as well (e.g. Zenject, UniRx come to my mind) and simple plugins are easy to integrate (add 1-2 asmdef total and reference them from where needed).

    @TeagansDad As I've done quite some work with asmdefs by now and run into this very often I just can tell you the package manager is PRETTY buggy when it comes to references and plugins like Text Mesh Pro. For TMP in particular I can just recommend: Save your custom TMP assets (fonts,....). Remove it completly. Delete your package cache. Readd TMP from the package manager. Let it load. Close unity. Readd your custom TMP assets. Reopen unity. That usually works.

    Also the package manager is very prone to breaking when you have a compiler error, e.g. a type not found, which causes it to sometimes fail without means to easily recover when you cant find a type required from a package (e.g. TMP) and then you have your dead-cycle. TMP not found -> Compiler Error -> Package Manager dies (even the menu item vanishes) -> TMP package not loaded -> TMP not found.

    Also after setting up your asmdef files close Visual Studio, delete the .csproj files and the .sln file and let Unity regenerate it. That also helps.

    Also a broken manifest.json can break the package manager and cause the dead-cycle above. Close Unity. Delete it. Open unity (it should regenerate). Recreate it.

    Also in case you tried to use the staging repository. Do not if you can avoid it. It is deliberately not recommended (some dev posted it in a thread somewhere in the addressables section where people tended to use it).

    @Wolk put the asmdef in your /Scripts folder. Put *.asmdef in the root folder of any ROOT folder you have scripts in (e.g. /Assets/Plugins for many people) and put a asmdef in any Editor folder of any plugin. If you have any Editor scripts also always but a asmdef in the plugin root folder. Mark the Editor asmdefs as Editor Only. Reference the <SpecificPlugin.asmdef> from the <SpecificPlugin.Editor.asmdef>. Put an asmdef in your Playmode Test root folder. Put an asmdef in the Edit Mode Test root folder and mark it Editor only. Reference all *.asmdef from which you require types from. Mark both Test assemblies as "Test Assemblies".

    Also for anyone in general: The Reference Selection Search does not always properly work with the packages/ asmdef. However what you can always do is lock the inspector, search the asmdef in the folder under /Packages and drag it into a new and empty array field. Also you can edit the manifest.json and manually add the correct name: e.g. "Unity.TextMeshPro"

    Edit: Important: I do not recommend anyone to have that many assemblies with Unity at the moment as it really slows down developement as it currently is - despite it should make it faster :). Keep the amount of asmdef as low as possible and as high as required to separate the concerns of your code base. The proposed approach simply helps to move from non-asmdef projects to asmdef-projects and visualizes bad architecture (cross references, cyclic dependencies, ...). It is way easier to merge two assemblies into one than to split an assembly into two.
     
    Last edited: Jan 21, 2019
    Whatever560 and karl_jones like this.
  21. khan-amil

    khan-amil

    Joined:
    Mar 29, 2012
    Posts:
    137
    Could we have a public field for that on the asmdef inspector? or at least a note for that in the documentation.

    For now, using asm files in conjunction with the addressable system is really not straitgforward, as it needs Unity.Resourcemanager but can't reference it from the asmdef inspector directly.
     
  22. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,283
    There's a public field for references. You can search for "Unity.TextMeshPro" when you add a new reference.
     
    MNNoxMortem and karl_jones like this.
  23. bitinn

    bitinn

    Joined:
    Aug 20, 2016
    Posts:
    544
    I am going to jump in and add a quick tip:

    Screen Shot 2019-02-22 at 15.35.42.png

    - If you are trying to make 2 separate assembly for monobehaviours and editor scripts, such as Cinemachine built-in Post Processing extension.

    - Make sue you set assembly containing monobehaviour scripts to also compile under "Editor" platform.

    - I made a mistake not doing that, and the editor assembly only complain to me about "missing reference to monobehaviour class", I had the reference set already, but the issue was I forgot to set it to compile for Editor.

    It took me one hour to figure this out...

    Screen Shot 2019-02-22 at 15.33.48.png Screen Shot 2019-02-22 at 15.31.19.png
     
  24. DrEvil

    DrEvil

    Joined:
    Aug 11, 2012
    Posts:
    18
    One problem with this system is that it doesn't reliably rebuild properly when you make changes to asmdefs in editor. I'm on 2018.3.6f1 for example and I have a source copy of TextMeshPro. I add a TextMeshPro.asmdef to the Scripts folder, I add a TextMeshPro.Editor.asmdef to the editor folder. I uncheck everything in TextMeshPro.Editor but "Editor", I add a reference to TextMeshPro.asmdef, apply both, it attempts to build and errors that a bunch of types defined in TextMeshPro cannot be found from files defined in TextMeshPro.Editor even though there is obviously a reference defined there. Only after I restart the unity editor does it seem to build properly.
     
  25. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    Could you file a bug report please?
     
  26. DrEvil

    DrEvil

    Joined:
    Aug 11, 2012
    Posts:
    18
    The issue is that I can't cause this bug in an skeleton project with the TextMeshPro source, yet it happens reliably in our large production project, so I'm not sure what I can really offer in terms of filing a bug for it.
     
    MNNoxMortem likes this.
  27. djlaserman

    djlaserman

    Joined:
    Mar 2, 2019
    Posts:
    1
    Trying to learn unity and getting so many errors even before I can press play! This is the number one reason I do not quite like Unity vs its known adversary... Seems you must first begin every scene with debugging, especially if you are using assets made by others. This I got in the 2019 build just after loading the 3D Game Kit... No time to debug, I want to create!
     
  28. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    397
    @djlaserman I doubth a new and empty project or a new scene will have any error on it's own. Once you introduce third party code you are always prone to introducing errors along with it, that is not unity-specific at all.
     
  29. BenjaminBachman

    BenjaminBachman

    Joined:
    Feb 1, 2017
    Posts:
    5
    We have the same problem for imported assets from the store. I am trying to fix this by having a pre-process step in the build which does the following:
    • Find all "Editor" folders containing .cs files but no .asmdef file.
    • Generate a .asmdef file inside the "Editor" folder with references to the next parent asmdef file.
    • Try to resolve dependencies between the "Editor" folders. (hoping that they are not circular)
    This works for some cases. Unfortunately there are assets (like ARCore) which have multiple Editor folders depending on each other and having "internal" classes. It is not possible to depend on internal classes of a different asmdef even if they are in the same namespace.

    Our alternative approach is hiding all .cs and .cs.meta files in "Editor" folders having no .asmdef file in a pre-process step and un-hiding them in a post-process step as was mentioned before in this thread. However this seems rather hacky and causes a re-import of the scripts at the end of the build.

    It would be much nicer if there was some kind of filter mechanism to tell the build pipeline which files to exclude.

    Did you already implement something along the lines of your approach with merging the Editor folders?
     
  30. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    In 2019.2 we have added a feature called Assembly Definition Reference files (.asmref). These let you add multiple additional folders to an assembly, so you can merge multiple Editor folders by simply placing an asmref file into each of them and linking them back to a master asmdef.
     
    Grumpy-Dot and MNNoxMortem like this.
  31. bdominguezvw

    bdominguezvw

    Joined:
    Dec 4, 2013
    Posts:
    92
    Any news on this @karl_jones ??
     
  32. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    Did a bug report gets filled? I don't see any mention in the thread of one. If its still doing this for you then please file a bug report.
     
  33. bdominguezvw

    bdominguezvw

    Joined:
    Dec 4, 2013
    Posts:
    92
    My problem is that it's not 100% reproducible in my case, it appears sometimes only. I don't know how to reproduce it but I think that that "*.Player.csproj" could give you some hint because there has to be some code on your end generating those specific files in some conditions.
     
  34. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,544
    Wow these things are a nightmare.

    For the rest of the scruffy DIY coders- if they turn up in your projects and put the brakes on just delete them to get your project going again.

    They're a feature for speeding things up that in practice bring things to a halt by the looks
     
    MNNoxMortem, AmitSuri and deab like this.
  35. iSinner

    iSinner

    Joined:
    Dec 5, 2013
    Posts:
    130
    I wonder if anybody else experiences the issue i'm gonna describe, and if yes, is this expected? because it doesn't seem to be correct.

    I have the following structure of folders



    OctreeEditorAssembly references OctreeAssembly
    OctreeAssembly references Core

    So the chain is OctreeEditorAssembly -> OctreeAssembly -> Core
    and the issue is that scripts from OctreeEditorAssembly don'y see scripts from Core. I have to add Core as a reference to OctreeEditorAssembly explicitly, even though it should be referenced through octreeAssembly.

    Is this intended?

    PS Unity 2018.4.6f1
     
  36. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    This is intended, it is how standard .Net assemblies work, you can only access the public type infomation of direct references.

    Essentially you have OctreeEditorAssembly.dll -> OctreeAssembly.dll -> Core.dll
     
    iSinner likes this.
  37. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    202
    Maybe it's possible to set a folder name on an ASMDEF by which it crawls the hierarchy it was assigned for and compiles everything that's in those folder. Like collecting Editor folders into an ASMDEF.
    I know with ASMDEF Reference files this is possible, but this would be a one shot for Editor folders from the outside.
     
  38. SugarChap

    SugarChap

    Joined:
    Jan 19, 2015
    Posts:
    15
    We have a recurring issue in our project which occurs as follows. (2018.3.8)

    1. The build gets in some kind of bad state - perhaps a library file becomes corrupted...
    2. Reimport all (last resort I know)
    3. Build errors occur on restart of unity - all relating to the script files in the root Editor folder. (This has it's own editor only asmdef that relies on all other .asmdefs.) All assets, components etc. are covered with "Script cannot be loaded".
    4. Toggle the 'Editor only' button on the editor .asmdef and hit 'apply' to recompile the editor scripts.
    5. Everything now compiles! BUT all links in the project are lost.

    The project is now in an unrecoverable state.

    This is a pretty frightening state of affairs for our team. The only way I can get the project back is to hand copy the entire project folder from a colleagues machine onto mine (or begin making whole folder local backups myself).

    The reason that we are using .asmdefs is not for the potential compilation speed benefits, but because we are using Pro Build and the Test Framework, both of which require us to.

    Any help on this would be appreciated. I would be happy to avoid .asmdefs altogether for the time being if I could still use these features.
     
  39. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,505
    Could you please file a bug report?
     
  40. SugarChap

    SugarChap

    Joined:
    Jan 19, 2015
    Posts:
    15
    Done - sadly without projects (upload kept failing).
     
    karl_jones likes this.
  41. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,283
    If your project is too large for the bug reporter to handle, you should state that in the bug report. QA usually sends you an upload link where you can upload larger things.
     
    MNNoxMortem, karl_jones and SugarChap like this.