Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Asmdef with subfolders?

Discussion in 'Scripting' started by MaximumTre, Jun 13, 2023.

  1. MaximumTre

    MaximumTre

    Joined:
    Nov 28, 2015
    Posts:
    163
    There is a thread about this that is from 2021 or something, I am having the same issue. Is this not possible? I want to cut down compile times as I have my own code then a few heavy assets I've added. I need to be able to put an asmdef in the root folder of each asset and have all the scripts therein included. Is this not possible?
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,882
    Might help to link to the original thread?

    Assembly Definitions apply to the scripts of the folder they're in, and any sub-folders. If you make another assembly definition asset in one of these sub folders, scripts in that folder and its sub-folders will be compiled into that new assembly.
     
    Ryiah, Bunny83 and Yuchen_Chang like this.
  3. MaximumTre

    MaximumTre

    Joined:
    Nov 28, 2015
    Posts:
    163
    What would cause this to not work? I have scripts in subfolders that throw a ton of errors about namespaces or type names not being found. This doesn't work for any of my folders either, I'm using multiple asmdefs throughout my project.

    The post in question didn't have an answer, hence why I'm asking.
     
  4. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,882
    Probably because you didn't reference the other assembly definitions each assembly requires: https://docs.unity3d.com/Manual/Scr...finitionFiles.html#reference-another-assembly
     
  5. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    287
    An asmdef does not reference other asmdefs by default, and they cannot reference the default predefined CSharp assembly. They will automatically reference precompiled dll assemblies that are marked auto reference, but not another asmdef. If an asmdef is marked auto reference, it is only automatically referenced by the predefined, default CSharp assembly. You must specify if an asmdef should reference another asmdef. (And just for clarity a precompiled dll assembly only references the other assemblies it needed to reference when it was originally compiled, including being pointed to things like UnityEngine.Core.dll, and it assumes that any such dependencies will be available when Unity compiles your project.)
     
    Last edited: Jun 13, 2023
    Ryiah, Bunny83, orionsyndrome and 2 others like this.
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Ditto on everything Spiney and CodeRonnie said. You need to setup your assembly references if they rely on code found in another assembly.

    Be careful though, you can't have circular references. This is why what CodeRonnie said in regards to how an assembly can't reference the default CSharp assembly... well that's because the default CSharp assembly reference all these asmdef assemblies you've created. And you can't have a circular relationship.

    So say you have asmdef A that is your UI, and you have asmdef B that is your Level Controllers. Welp... you need to pick now. Either A can ref B, or B can ref A. Not both.

    Really you should be thinking of assemblies as a whole new layer of encapsulation (if you're unfamiliar with encapsulation, it's a core principal of oop). Assemblies don't exist specifically to speed up compilation, that's just a benefit. Assemblies exist to organize your code.
     
    SisusCo, Ryiah, CodeRonnie and 2 others like this.
  7. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,882
    Agree with lordofduct above. Namely, your code needs to be organised with assembly definitions in mind from the outset. It's not something you can throw in as a afterthought, as your code structure is likely to not be compatible with the one-way nature of assembly definitions.
     
    SisusCo likes this.
  8. MaximumTre

    MaximumTre

    Joined:
    Nov 28, 2015
    Posts:
    163
    Ok thanks for the basic info about how asmdef's work.

    The issue I'm having is that I have a folder, lets call it Main Folder, inside main folder there are other subdirectories. Sub Folder A, Sub Folder B, etc.

    The asmdef is in Main Folder and doesn't require any other asmdefs except stuff like UnityEngine.UI etc. Those are linked as they are supposed to be.

    The problem is Scripts in Sub Folder A and B aren't able to use the stuff under the same namespace in the asmdef that is in Main Folder. From what I understand, sub folders are supposed to be in the main folder asmdef. Is this not the case, and if so what would cause this? Because as I said, the code in sub folders A and B are in the same namespace as other scripts in the Main Folder. Do I have to have an asmdef in EACH subfolder for stuff that is in the same namespace? That doesn't make sense at all if so. This is my project's namespace I'm talking about here, there isn't anything else being used in these sub folders. I moved them out of the main folder to for organization.
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    The subfolders is not your problem, I can assure you of that. I do the subfolder thing all the time. Case in point you can see here:
    upload_2023-6-13_21-15-13.png

    There are various asmdef's all with no source files adjacent to them, only source files in subfolders of them.

    Your problems are going to be rooted in those errors, without knowing what those errors say specifically, I can't tell you EXACTLY what you need to do. But whatever it is, since you say it is "namespace" or "type name"s not being found. It's because your asmdef's aren't referencing the necessary assemblies.

    So just ignore the whole subfolder thing for now.

    Lets say you have this "Main Folder". Do you have any source files that are located NOT as a child (subfolder or not) of "Main Folder"? And if so, are they referenced by the source files inside "Main Folder"? Note that this could include references to types found in 3rd party things like packages you've installed. Think like TextMeshPro or UniTask.

    If you look at the errors in question, they'll say which types and/or namespaces can't be found. The assemblies, 3rd party packages, etc from which those types and/or namespaces are from are the ones that your asmdef don't have references to and need references.

    For example in my above image that 'DataBinding' library has conditional use of TextMeshPro, Addressables, and UniTask and so therefore I had to setup the asmdef like so:
    upload_2023-6-13_21-21-43.png

    Note - the 'version defines' at the end aren't necessary. Just the 'Assembly Definition References'. The 'version defines' are just because this assembly has conditional reliance on tmpro/unitask/addressables. Basically the library will conditionally compile sections of its code if and only if it finds those 3rd party packages installed.
     
    MaximumTre and CodeRonnie like this.
  10. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    On a tangent... I have to complain about something in regard to assembly definitions and this conversation about them speeding up compile times.

    I just don't agree that it does actually do that!

    OK, OK, OK... I will agree that it can speed up compilation in certain situations, BUT can also slow down compilation in other situations.

    Case in point this project above that I showed images from... that project is slow as all heck to compile any time I change something! And it's because if I edit code in say "com.spacepuppy.core", being the core assembly that many other assemblies rely on, a cascading of compiling seems to occur. Or at least that's what appears to be happening. Cause it takes a while to compile if I edit that. Longer than if I had the entirity of this spacepuppy just flat in a project.

    Of course... the upside is when I have spacepuppy imported into one of my games, I'm not generally editing spacepuppy, so it doesn't impact the compilation times of my game specifically.

    And that's what I mean... it speeds up compilation in a very specific way. It only speeds it up if, and only if, that assembly isn't being touched often and nor is the assemblies it references OR if that assembly isn't referenced by anything else. But if your assembly is both referenced by something (which is likely) and you edited it... it actually slows things down since now it has to individually compile that assembly and every assembly that references it.

    Or again, that's what it appears to be doing from how I've noticed.

    If I edit spacepuppy.core, which has lots of references to it, it's slow.
    If I edit spacepuppy.DataBinder, which has no references to it, it's fast.

    This isn't to say you shouldn't use asmdefs, and it's not to say it can't speed up compilation. It's just that I feel like whenever I see people talk about asmdefs speeding up compilation on the forums it seems like they think of it as some sort of panacea to their slow compilation woes.

    Personally speeding up compilation is NOT why I use asmdefs. As you can see in my pics above... I use them for organizing my packages.
     
  11. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,882
    So do these sub folders define their own assembly definition or not? If not, they're going to be compiled into whatever assembly is present in any of their parent folders, so I'm guessing this 'Main Folder'? If they are, they still need to reference the appropriate assembly definitions.

    You can click on your script assets to see what assembly they're compiled into.

    Yeah pretty much the same here. They reinforce good code architecture, keep my code modular, etc etc.

    The best way to speed up compilation time is just better hardware.
     
    Ryiah and lordofduct like this.
  12. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Yeah I pretty much agree with the overall sentiment about the compilation speed. I wanted to share my view early on, but lordofduct did it better, and I hoped someone would. It's really just a PR stunt. It was advertised as a holy grail of speed ups. It is not.

    I'm assuming that's like a hot point of comparison people use when comparing Unity with Unreal or Godot. Godot especially is known for very fast compilation times since it's using a custom python dialect and whatnot.

    That doesn't make it necessarily better in every thing it does, but I'm guessing they're fighting over the adopting population, because once you make a decision, it's harder to convert. And Unity PR sometimes falsely repurposes unrelated tech to build an argument. This is one of those cases.

    You know
    FAST COMPILATION TIMES -- CHECK * and then a small asterisk
     
    SisusCo, Nad_B and lordofduct like this.
  13. MaximumTre

    MaximumTre

    Joined:
    Nov 28, 2015
    Posts:
    163
    I'm really confused now, because I just knew none of my scripts were referencing anything that wasn't in the asmdef, but something keeps happening when I compile sometimes where there are a bunch of using statements added for crap I have never needed or even know how to use. So apparently there was something being referenced. I must have something else wrong in my project and I'm gonna go over everything again. I started with an asmdef to keep my code organized and reduce compile times. It works for reducing compile times, but organization is a bit annoying when I can't just reference one thing I need from some asset I'm using. Thanks for the help and the patience. Cause I ran out of mine.
     
  14. CodeRonnie

    CodeRonnie

    Joined:
    Oct 2, 2015
    Posts:
    287
    If you're working in Visual Studio, it may automatically add using statements while you're working. If they are greyed out, and the file is complete, you don't actually need them. If you click the clean up code button that looks like a little brush icon at the bottom of the page it will apply styling and remove any unused using statements. Also, just be aware that nesting one asmdef inside another creates a separate assembly that doesn't automatically reference the parent.
     
    MaximumTre likes this.
  15. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,051
    The situation was a bit different when asmdefs were introduced.

    At that point, Unity was still using an old Mono compiler that was much slower. Compilation was the major factor in iteration time and one big selling point of asmdefs was to help reduce compilation times in large projects. But Unity has switched the Roslyn compiler, which is much faster. Nowadays, compilation time is quick and it's dwarfed by domain reload time, so there's much less performance benefit in using asmdefs.

    This is also reflected in Unity's documentation, compilation time was the leading point when asmdefs were introduced, now it's just one of three points and only mentioned one time.
     
    Ryiah, spiney199 and Lurking-Ninja like this.
  16. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    @Adrian
    I agree with you but we're not talking about the same thing.

    I'm not talking about documentation, documentation was always fine, i.e. it didn't exaggerate. In fact the "small asterisk / print" in my example leads directly to documentation.

    I am talking specifically about PR, which gives people an idea of a massive boost only to be disappointed. The blogs, the talks, the announcements. What would otherwise cause such disappointment when the docs in 2017 clearly state the prerequisites
    Truly they never claimed that the compilation is guaranteed to be accelerated.

    Also the first version of IL2CPP was introduced in 2015
    It wasn't in full swing yet, but predates asmdefs.
     
  17. MaximumTre

    MaximumTre

    Joined:
    Nov 28, 2015
    Posts:
    163
    IDK about holy grail of speedups, but it does help to speed up compile time in my project. My compile time on my crappy lappy went from 30+ to around 10-12 seconds.
     
  18. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    You organize your codebase into separate assemblies so that it doesn't have to recompile entirely on every change. Technically that's not a speed up per se, but it was regardless promoted as a long awaited improver of compilation times. I'm trying to show why this particular play on semantics is disappointing to many people.
     
    MaximumTre likes this.