Assembly Definitions
Can someone dumb this down for me? I'm trying to decrease compile times for unity and came across this(image + link) but this seems really complicated š
https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html#:~:text=An%20assembly%20is%20a%20C%23,define%20references%20to%20other%20assemblies.&text=Every%20time%20you%20change%20one,time%20for%20iterative%20code%20changes.
154 Replies
if this is something i shouldnt bother with or touch, let me know. i just dont like having to wait 20+ seconds every time i save a script š¦
mb
wait was this ur answer to my question or were you fixing the link i sent
i went through this recently
Unity by default puts ALL of your scripts into a default assembly called AssemblyC#-default or something like that
This default assembly depends on all your packages
in order to add an assembly definition, in unity, your two options are:
1) Define your own dll which explicitly calls out every package dll etc that it depends on
2) hook up Unity Assembly Definition assets
a Unity Assembly Definition makes an assembly, and automatically adds ALL code in that folder or a sub folder to that assembly UNLESS it is covered by either 1) its own .dll or 2) One of the subfolders has an assembly definition (asmdef). In which case it does not include that folder or any subfolders
to make an Assembly definition that is equivalent, start by making an asmdef in your root folder, and make it depend on all the .asmdef that you use in your Packages folder.
that is what tripped me up for the longest time.
I think this may be out of my league š
itās not hard, but it will only benefit you if you can actually totally separate a large chunk of your code intona separate assembly
right now, you can just put an Assembly Definition asset directly into your Assets folder.
and then on the little list of dependencies in the inspector, you add all the asmdefs for packages you use. Like NaughtyAttributes.core
Like typical unity inspector, it will show you only the asmdefs in your project. And since you havenāt made any, it will only show you package asmdefs
If you do this, then all of your code should still work the same as before (except maybe anything that depends on assembly qualified names of types, which you probably have none of)
āā
Later, you can add assembly definitions to different folders, if everything in that folder is kind of separate from the rest of your project. Then make the root asmdef depend on that new subfolderās asmdef. Now Unity wonāt recompile anything in that subfolder unless you modify it.
Understand?
lets start here, what asset and into the in-Editor assets folder?
oh thats an actual object
is this where i list all of the "asmdefs" for packages i use? and i dont know where to find/reference those
I assume all of your own scripts are in subfolders of subfolders of subfoldersā¦ of the Assets folder
Keep in mind there is Assembly Definition (what I was talking about), and Assembly Definition Reference. Assembly Definition Reference is an asset that targets an Assembly Definition to add the folder that the assembly definition reference is in, to the set of folders that the Assembly Definition will try to consolidate into one assembly.
In the inspector, Assembly Definition has a field for Assembly Definition References, which is actually a list of asmdefs that this assetās assembly depends on. And is not an Assembly Definition Reference asset. Yes it is confusing
add one entry to the list, then click on the empty entry, and unity will show you any asmdefs in the project (packages included)
they should have obvious names that reflect the relevant namespace
like if you use Unity Tilemaps, you would select UnityEngine.Tilemaps, which is the namespace that Tilemaps is in
I see, but I donāt know which I use
Oh I see, I added input system and a lot of errors disappeared
donāt touch asmref (Assembly Definition Reference asset) files until later.
Oh I donāt know what that is
yes, because now your code is in an assembly that depends on UnityEngine.InputSystem
Do I just add them based on the errors I encounter? That seems kinda janky
you canāt use code from outside an assembly unless the assembly of your corde depends on the assembly of the code you are trying to work with
if you are using InputSystem, your assembly needs to depend on it
Iāve never been more confused in my whole entire life š¦
you know how you have using UnityEngine etc in your code?
yeah arent those libraries
you are bringing in code from a different namespace
when you download a package, that package is normally in its own assembly
and usually also with its own namespace
assemblies change what code is compiled when
if your code is using InputSystem, and InputSystem is a different assembly, then your codeās assembly needs to depend on whatever assemnly has InputSystem
because the whole InputSystem namespace doesnāt exist outside of that assembly
ok so by adding this assembly and telling it to reference Input System, it will only compile Input System scripts?
almost
if InputSystem changes, and your codeās assembly depends on InputSystem, then the compiler needs to compile BOTH fresh
does this new assembly become the only assembly? why does it throw errors if i have nothing in its references
if your code changes, and Inputsystem does not change, but your codeās assembly depends on InputSystem, then compiler will recompile your code, but NOT InputSystem
ok i understand that part
the way I described, yes. It throws errors because the default unity assembly automatically depended on all your packages
oh ok
weāre first making one root assembly to replace the default assembly
the root assembly I told you to make does NOT automatically depend on all your packages
i understand
thatās why they need to be added now
why cant i just tell it to depend on all my packages? and if i dont use them, it wont compile them every time
idfk
it would be too simple
fair enough
so am i supposed to add the packages based on the errors it throws?
granted i can go off of just.. the ones i know im using
but i dont think ill remember to add every single time
no. but the errors it throws will let you know you actually missed a dependency
ok so i am expected to manually add every one i use ever
like if you use InputSystem functions and classes, but never write using InputSystem, compiler throws error because it has no idea wtf youāre talking about
same thing with assembly
but you donāt want to micromanage a lot of tiny assemblies
remember assembly dependencies cannot be cyclic. So if classA uses class B, and class B uses class A, then both have to be in the same assembly
but if you have A B C all use each other, and nothing else, then A B C can all be one separate assembly
how do i know which to add? or is it simply just the
.cinemachine
oneso, youāll see a lot of asmdefs with editor in them
but can they all be in the same assembly if they dont use each other
editor basically always means UnityEditor, like inspector.
Almost always, editor scripts are in an editor assembly definition, and this editor asmdef depends on the core stuff of your project
you lost me
they can. but then changing one makes you recompile everything
oh
your unity code for your actual game should never depend on the code for your custom unity editor. Like the scripts that change the inspector
because your game isnāt run in unity editor
yeah that makes sense
i dont know what an asmdef is, is that the editor?
so usually all your editor scripts go into one big separate assembly
and i just dont touch that ever
asmdef is the file extension for assembly definition asset
that is fine, but you will download many packages with .Editor asmdefs
we do not want any of that shit in the actual game
what about the current ones? do i want to add those? to the non-game new assembly
i add only as needed
ok.. going back to whether or not i need a new assembly for in-game packages, i need help understanding that
i have my editor asmdef, and it depends on my main assembly, and all my package editor asmdefs.
My main assembly does NOT depend on any packageās .Editor asmdefs, or else you fucked up
you lost me again xP
i edited last sentencep
your gameās main assembly does NOT depend on ANY editor scripts
yes
therefore, your main ingame assembly does NOT depend on any of the .editor asmdefs from your packages
because those asmdefs correspond to editor code
which we donāt want
and how do i identify an asmdef
it just says .Editor?
this dropdown shows all your asmdefs
so everything i see is an asmdef
yeah, that little puzzle icon is an asmdef
ohh ok i understand what you mean now for which not to add
yeah, editor asmdef should depend on package editor asmdefs. Ingame asmdef should not
rn i need to understand when to make a new assembly for in-game packages or to add them to an already existing assembly for in-game packages
and should i make a new assembly only for .editor asmdefs (and which to add there)
if you donāt include an editor asmdef as a dependency of the main assembly, and your compiler is confused, you fucked up.
whats the main assembly? i thought that already knew about everything
yes
the asmdef i told you to put in the root of Assets
we will not be using the default assembly anymore
im confused
so that will be our equivalent of it
so i add in-game packages to the main assembly
i dont add editor packages to the main assembly
if i dont add editor packages to the main assembly and compiler = confused, i did something wrong
the moment you put an asmdef, it collects everything (all .cs from folders and subfolders) into an assembly for it.
right now, everything you have is in the default C# assembly because you have no asmdefs
but its not because it throws errors
when i add the blank assembly object
the moment you add an asmdef, compiler is confused because you reference code from an assembly you donāt depend on.
so you add dependencies to that asmdef, so it knows to make the assembly depend on the assemblies containing the missing code
oh ok u were talking about before i added anything
yeah i get that much
yes. this is the timeline
ok, so now everything works.
i dont understand this part
hold up.
or when to add asmdefs to already existing assemblys or to create new ones
this asmdef that you just made in the root of Assets, it contains NO dependencies to editor code
i just added the stuff that threw errors
then weāre going to a different folder, we add an asmdef for editor, we make it depend on any .Editor asmdefs we need, and depend on the main assembly we made before. and now that folder and everything in it is in a separate editor assembly
read the errors
there are no more errors
there you go
why do i have to make a new folder?
2 asmdefs cannot exist in the same folder
oh
that Editor folder is going to contain any editor scripts you ever make for your game
which might be none, but now you have a separate place for them
when do i use an assembly definition reference?
oh nvm thats just what u mean when u say asmdef
and the option to create one is for if i wanted to make a package or whatever
i assume
lets say you have myClassA.cs in folder A, and myClassB.cs in folder B. You want them in one assembly, but they arenāt subfolders, they are in different folders, and you just want to tie them together. Give folder A an asmdef to define the assembly. Give folder B an asmref (REF) that targets the asmdef if folder A
now A and B are part of one assembly
yep you lost me again lmao
that is an Assembly Definition Reference Asset
an asmref file just connects the contents of one folder to be counted for an asmdef
asmrefs just change the part where asmdefs check all folders and subfolders
is that something i want
sometimes, but not right now
alright
the naming is very confusingp
how do i know what to add to the editor assembly?
when it doesnt throw errors
editor assembly will probably depend on your main assembly
and any .Editor asmdefs if the packages folder
does that mean i put the editor assembly in the main assembly
or vice versa
but you only really need to manually write dependencies for the shit that YOU actually use in your code
just all of them? whether i know im using them or not
even for the editor?
you only need the ones you actually use
for everything
idk which im using
or are there no default
compiler will imediately let you know when you fuck up
because it will tell you that X file does not know about Y namespace
so input systems go inside editor assembly?
only if the scripts that you have in the editor assembly use it
which is currently none
doesnt the editor use it? outside of the game
the asmdef only applies to code in that folder and subfolders
if that folder and subfolders are empty, there is no actual code in the assembly
i dont understand what counts as a Editor asmdef here
because i use input system in the unity editor to assign hotkeys for in game
you see the asmdef Cinemachine.Editor
that is an asmdef intended to ONLY be used for unity editor mode
and never for the actual game
so your game assembly does not depend on Cinemachine.Editor
ok and so the default setup doesnt count for the editor assembly? only extra scripts that i add?
but maybe you write an editor script that uses stuff in Cinemachine.Editor. then you will want that in your special editor asmdef
oh ok
so i dont care about the default unity stuff
only scripts i add to modify it
that just exists there
yeah now it makes sense
UnityEngine has its own assembly.
do i add main assembly to editor assembly? or the other way around
the autoreferenced checkbox automatically puts all that stuff in there
other way around
editor code depends on your code because it needs to know what classes it is an editor of
so within main assembly, alongside the input system and cinemachine asmdefs, i add EditorAssembly?
the classes for your game do not need to know about the editor classes that edit them
NO
main assembly does not contain anything with the word āEditorā in it
i mean the assembly i created
the EditorAssembly
i add that to main?
Editor asmdef does reference the main assembly
im confused again
do i do this
NO
isnt that what you said here?
in what i sent, i put the Editor Assembly in the Main Assembly, is it supposed to be the other way around?
editor assembly into a folder in Assets
because it cannot be in the same folder
thats what i did, first image
this is wrong
in this list
do i put Editor Assembly
in this list
no
i keep saying no
so i go to editor assembly
and add main assembly?
yes
ah ok that was the first question i asked but u said other way around xd
just to double check, i can apply this?
there you go. done
alright cool
gg
gg no rematch
so now
im good to put everything i use in the main assembly, except for anything i use to do with editor, which goes in editor assembly?
yes
so what did it mean when u said earlier about different assemblies if x and y reference arent used with each other
this part
that is the basics of an assembly
In this case, A B and C must all be in an assembly together in order to use each otherās code.
but because they donāt depend on anything else, they can be in their own assembly
but i dont care about that
right?
thatās like the whole point of using assembly definitions. So your code wonāt have to recompile everything all at once
like what if one script uses A , B, C and D and another uses D and E
would A B C and D be in its own assembly, then D and E in their own? or would E be included with ABCD because D is included in ABCD and AE
not necessarily
as long as ABC only use each other, they can be in a separate assembly (or added as one unit to any other assembly)
if a script uses A, then its assembly needs to be OR contains the assembly with ABC
but can one be used in multiple?
like A B in an assembly, and A C in a different assembly
this is way beyond the scope of this thread, brother. this is just more generic assembly stuff
alright i wasnt sure because you mentioned it
so i think everything is good
compiling after a one-character change still took a good 5 seconds but i think its down from previously
anything else you think i should know?
you got the basics. good luck
thanks for the help. ill reference your previous messages for when i need Assemble Definition References
oh and try to write code that fits into a separate assembly, by making things that donāt depend on your main code base
so you can combine them into a separate assembly