Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

Example Project - Assembly Definition Files

Discussion in '2017.3 Beta' started by LeonhardP, Jul 8, 2017.

  1. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,713
    Important: Assembly Definition Files postponed until Unity 2017.3.

    The assembly definition files feature will be disabled in the final release of Unity 2017.2.

    The development of the feature was not completed for the release of Unity 2017.2 and is postponed until Unity 2017.3.

    Keep an eye out for when the Unity 2017.3 betas become available and try out this feature with complete editor integration.


    -

    Hi everybody,
    I'd like to share with you an example project to demonstrate usage and capabilities of user-defined managed assemblies, a new feature in Unity 2017.3 with the potential to drastically minimize script compilation times of your projects.

    This example project consists of two scripts that run in the editor. One to measure and display editor compilation times in the console, and another to generate lots of generic scripts in separate folders and corresponding assembly definition files. This way you can experience the performance differences custom managed assemblies afford first hand, without having to setup things yourself.

    To get started, simply download the project via the link below and open it in 2017.3. The test scripts and their assembly definition files can be generated by clicking on ‘Generate’ in the menu bar.



    The purpose of these scripts and assembly definition files generators is to give you quick access to see what impact custom assemblies can have on compilation times in projects with lots of scripts. The 'Generate' menu in the menu bar is exclusive to this example project and not part of the feature itself.

    Project link ( 93 kB):
    https://oc.unity3d.com/index.php/s/GoVSG4ngRJDFyDC

    You can find more information about the update of the script compilation pipeline, assembly definition files, and how to use them here:
    https://drive.google.com/file/d/0B51Vmelt0rENZThZOTl5ZTIyN28/view?usp=sharing

    Please use this thread to discuss the subject matter.


    Edit (10/02/17):
    Updated the project to reflect the change of the definition file type from .json to .asmdef.
    Edit (09/27/17):
    Migrated the thread from the 2017.2 beta forum to the 2017.3 beta forum.
    Edit (08/02/17):
    Revised folder layout and naming.
     
    Last edited: Dec 20, 2017
    nirvanajie, codestage, Novack and 2 others like this.
  2. Jes28

    Jes28

    Joined:
    Sep 3, 2012
    Posts:
    420
    Hi

    Why Assembly Definition info is stored in separate not Unity object text(json) files instead of folder meta files and editor support on it?

    Even if this is necessary to have separate file why not use ScriptableObject with exact structure, correct Editor In Inspector and easy script access?
     
    Harinezumi and ortin like this.
  3. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    The reason we use json files is because we want to standardize the format of the assembly definition files so they can be read and written by third party tooling.

    The serialized data format in Unity is not standardized nor documented and could change at any time.

    An inspector for the assembly definition files will land in Unity before 2017.2 is released.
     
  4. TFlippy

    TFlippy

    Joined:
    Nov 12, 2014
    Posts:
    23
    Opening any of the scripts in Visual Studio Community 2017 results in an error for each of the generated assemblies, with them missing afterwards in the Solution Explorer. Shouldn't they be suffixed with the assembly name, such AssemblyDefinitions_ExampleProject.Folder0?

     
  5. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    This is a known issue in the Visual Studio Tools for Unity (VSTU) that has been fixed. The fix should be available in the next release of VSTU.
     
  6. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    This actually prevents to test this feature at all.

    Any idea when the update will be available for VSTU?
     
  7. xKosta

    xKosta

    Joined:
    Oct 15, 2014
    Posts:
    22
    I love this new feature a lot. I have successfully created assemblies with Visual Studio 2015, but I am asking myself, will there be also a Visual Studio CSharp Project available? I would like to split parts of my application into different assemblies and c# projects by using this feature. Like Unity does with Editor and Plugins today.

    Keep up the good work!
     
  8. jbevain

    jbevain

    Microsoft

    Joined:
    Feb 22, 2012
    Posts:
    136
    Hello folks,

    Jb from the VSTU team here. In the meantime, we're making non supported beta builds available for those of you who want to try this feature:


    For 2015, just close all Visual Studio instances and install the .msi. You can always revert to the last stable version.
    For 2017, you'll need to install the .msi, and also to install the .vsix in your Visual Studio 2017 instance.

    Let us know if you have any issue.
     
    Last edited: Jul 14, 2017
    mindfulmx likes this.
  9. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    421
    I'm using VS2012 and it works quite fine. Anything I need to know though?
     
  10. TFlippy

    TFlippy

    Joined:
    Nov 12, 2014
    Posts:
    23
    Works perfectly, but how do I reference the default script assembly? Using "ProjectName", "ProjectName-CSharp" or "Assembly-CSharp" doesn't seem to work.

    This is needed for imported scripts from the Asset Store that use the Editor folder, which gets overriden by custom assemblies.
     
  11. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Hi

    The assembly definition files cannot reference the default script assemblies (Assembly-CSharp, etc.). As this would create cyclic references, as the default script assemblies have automatic references to to all compatible assembly definition file assemblies.

    Just like the default assemblies have automatic references to all compatible pre-compiled managed assemblies.

    I'm not sure what you mean by "This is needed for imported scripts from the Asset Store that use the Editor folder, which gets overriden by custom assemblies."

    The assembly definition file assemblies do not override anything in the Editor folder unless they are put inside the Editor folder. Which I think should be avoided. If you have editor only assemblies, you can just specify that it in the "includePlatforms" in the assembly definition file and put the file in any folder in your project.

    The current documentation does not explain these details, but it will be addressed in the final documentation in the Unity manual.
     
    Bshsf_9527 and Zbad like this.
  12. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    421
    I think @TFlippy is talking about something I was also mentioning here.

    It's about assetstore packages. If I want to commit an editor tool to the AS and my tool is referencing the UnityEditor.dll, how will that work out if the user, who is downloading my package is using a different version of the UnityEditor.dll?
     
  13. TFlippy

    TFlippy

    Joined:
    Nov 12, 2014
    Posts:
    23
    I'm currently using FullInspector from the Asset Store for its inspector extensions, which utilizes several attributes to determine how the objects are serialized or appear in the inspector. But since I moved it in its own assembly in order to be able to use those, the "Editor" folder inside the addon gets ignored and compiles unconditionally when building the game (which results in an error, as it can't include Editor-related stuff).

    Would have it been possible to add a way to have them conditionally compiled / ignored similiar to the way the Editor folder works?
     
    Last edited: Jul 16, 2017
  14. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    @TFlippy Try moving the Editor scripts from FullInspector in a new folder under Assets\Editor and set a different assembly for that(e.g. FullInspector-Editor).

    That should do it.
     
  15. mihakinova

    mihakinova

    Joined:
    Jan 6, 2015
    Posts:
    85
    Any idea if this works / will work with JetBrains Rider?
     
  16. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,119
    What's the workflow when we add, remove or rename a script?
     
    Last edited: Jul 19, 2017
  17. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Jetbrains team are aware of the feature and looking into anything necessary on their end to support this. But the .sln file should be working correctly, as it uses the same .sln generator as we use for MonoDevelop.

    Assembly definition files do not contain any references to script filenames and includes all scripts in the folder it is located it (and child folders, if those do not contain assembly definition files). So adding, removing and renaming scripts does not require any additional editing of the assembly definition files.
     
  18. IvanShakhov

    IvanShakhov

    Joined:
    May 19, 2016
    Posts:
    32
  19. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    I have a one improvement request.

    Currently, the generated csproj lists files using full path from the root of the Assets directory. So if we have an assembly in following structure:

    Assets / Code / Assembly1 / Assembly1.assembly.json
    Assets / Code / Assembly1 / Script1.cs
    Assets / Code / Assembly1 / Utils /Script2.cs

    Both project would contains "Assembly / Code / Assembly1" folders until they actually start showing script files relevant to our assembly. So it would be:

    Assets -> Code -> Assembly1 -> Script1.cs
    Assets -> Code -> Assembly1 -> Utils -> Script2.cs

    Since we are only presented in files at or below the level, where assembly definition file is located, would it be possible to display the files in relation to where assembly file is located, instead of in relation to the root of Assets folder?

    In the example I would expect that the project would contain files like this:

    Script1.cs
    Utils -> Script2.cs

    I think this is probably more a request to VSTU, not unity. However, it would make some external tools, like Resharper work way better in respect to the namespaces, most probably we do not want to have "Assets.Code.Assembly1" in our namespace.
     
    OndrejP likes this.
  20. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,119
    Gotcha, so what you've decided to implement is an extension to the already existing folder structure where Plugins and StandardAssets have their own .dll
    It's not bad but why didn't you chose namespaces as a split boundary? I mean if you look at who knows about interdependencies, it's not the level designer, not the animator or anyone else that has the ability to move files around the project, it's the programmer, so why not bind assembly definition to the code itself? That was hinted a few years back by Lucas and made so much sense from my end that I started using namespace :)
     
  21. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    I think you misunderstand. Assembly Definition Files don't define projects. It defines whether some subfolders of Assets will get compiled into a different assembly or whether they'll get compiled into the main assembly.
    The project at the end will still be one and it will contain all the scripts , like before.
     
  22. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    That's why I mentioned this request is more targeted to VSTU, since it's the addon which generates the project files according to assembly files definition, as far as I understand.
     
  23. mihakinova

    mihakinova

    Joined:
    Jan 6, 2015
    Posts:
    85
    I'm not sure that's the case. As far as I understand, Unity will only rebuild assemblies that have been changed. That's the actual point of this, if you have a big part of your code that rarely gets changed, you put it in a separate assembly, and so it won't get recompiled when you change one of your other scripts.
     
  24. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    There won't be any projects generated. You will only have the one project for all of Assets.
    Say you have two folders.
    Assets/MyAssemblyScripts1
    Assets/MyAssemblyScripts2

    You have only created Assets/MyAssemblyScripts1.assembly.json.
    So Unity now knows whenever it recompiles the assemblies that ALL scripts under Assets/MyAssemblyScripts1 will go into <assembly_name_given_in_assembly.json>.dll.
    But since you haven't created an assembly.json file for MyAssemblyScripts2 folder then ALL the scripts under it will go into the regular Assembly-CSharp that all code compiled into before.

    You still have only one project which is <ProjectName>.csproj

    The plus side is that when Unity recompiles due to a change, it will check if the change happened in a script that's under MyAssemblyScripts1 folder or not. If it did, Unity will only recompile the MyAssemblyScripts1.dll but not the Assembly-CSharp.dll. If the change happened in a script under the MyAssemblyScripts2 folder, then there's no reason to recompile any script under the MyAssemblyScripts1 folder. It will recompile though, ALL scripts that falls under the Assembly-CSharp assembly,including all scripts in the MyAssemblyScripts2 folder.

    At this point there's no real need for a different project. If you want to isolate code tracking in versioning systems, just have MyAssemblyScripts1 be its own repository(Nested under any projects that will need it).
    If you need to redistribute the dll, just grab the dll that gets compiled and use it in the Plugins folder of another project. Personally though, I like the idea of having the code of the "library". You can easily do changes without all the MSBuild hackery and ProjectFileHook stuff to rebuild the project and also copy/move the resulting assembly in an appropriate folder under Plugins to update the library being used in the core Unity project.

    Another upside is that, before, if you wanted to have a cs library project which provided MonoBehaviours and you had also created CustomEditors for them, you needed to also have an extra cs library project for the Editor scripts. Something people from Unity told me several months ago. Now this is as easy as bundling all Editor scripts for the "library" in a folder and add a <folder_name>.assembly.json file to it. Presto.

    Is there any other reason to use normal CS Projects at this point? I can't think of any.
     
    Last edited: Jul 20, 2017
  25. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Is this true for VSTU? @jbevain can you comment?

    The built-in MonoDevelop/VS Code/Rider solution/project generator will generate a .csproj for each assembly in the Unity project. It thought it was the same for VSTU. The assemblies and dependencies specified in the assembly definition files must be used in the IDE to help reduce compilation times when building in the IDE.
     
  26. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    Hmm...I read the link above but it said nothing about creating separate csproj files as a result. Just said it would separate the project scripts into different dlls. Ok then my bad.
    @rastlin Seems like I misunderstood afteralll. Sorry about that. For what it's worth, after reading the lukasz' comment, I tried the generation with MonoDevelop(can't change VSTU now..) and there the generation only keeps the assembly folder as the root in the generated project.
     
  27. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    VSTU does generate csproj file for each assembly definition file.

    Currently the generated folder structure in the project looks like this:


    In my opinion Assets->Assets->Scripts->FolderX structure is redundant, it could be cleaner if it could look like this:


    I spend 80% of my time in IDE, chance I'm, more interested in how this feature interacts with IDE rather than Unity itself. In my current workflow I'm using in 2017.1 I have exactly the same structure as the definition file provides, I'm just building my assemblies independently in IDE and copying them to Assets folder for Unity to reimport.
     

    Attached Files:

    • vs1.png
      vs1.png
      File size:
      6.9 KB
      Views:
      2,505
    • vs2.png
      vs2.png
      File size:
      6 KB
      Views:
      2,563
    Mikael-H, hadrien_g and Peter77 like this.
  28. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    Do you have an extra Assets folder inside the root Assets folder? Or is this a bug in VSTU?

    I wonder if there's a reason for the folder structure present though.Even the previously generated Editor project kept the same Assets root folder in it and based all scripts as relative to Assets instead of Editor.
     
  29. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    Yes, it's from example project, it has a duplicated "Assets" folder in it, it's not a bug.
     
  30. vestigial

    vestigial

    Joined:
    May 9, 2015
    Posts:
    68
    Is it possible to use assembly definition files when the C# code has conditional compilation? Specifically I'm trying to wrap FlowCanvas from the asset store in a flowcanvas.runtime.assembly.json. But, some code is wrapped in #if UNITY_EDITOR. Not picking on FlowCanvas, its just a good example. Is code not suitable for assembly definition files if it contains conditional editor-specific compilation? I know about includePlatform:["editor"] but in this case, the files are not editor files.
     
  31. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Conditional code will work fine. The assembly definition files assemblies are compiled with the same defines/references as scripts that are outputted to Assembly-CSharp and friends. They will be compiled with editor defines in the Editor and with platform specific defines when building players.
     
  32. sbergen

    sbergen

    Joined:
    Jan 12, 2015
    Posts:
    5
    EDIT: I misread something in this thread, and after revisiting the feature document, I noticed that dependencies, aka references are defined manually, so all good! You can ignore the below :)

    We are currently using our own separate solution with multiple assemblies, together with a solution post-processor that injects the projects from that solution into the generated solution. Great to see that we should be able to get rid of this build customisation, as it periodically causes some issues!

    One thing I'm concerned about though, is that the dependencies between assemblies are automatically deduced. I would much rather define them explicitly. I see this causing two kinds of issues when you accidentally reference something from another assembly. This can cause two kinds of issues:
    1. It might break the design principles without being warned, causing just generally bad spaghetti code
    2. You might later run into hard to fix cyclic dependencies, as you didn't pay attention to dependencies properly from the start.

    I would much rather define dependencies manually, than have them automatically added!
     
    Last edited: Jul 27, 2017
  33. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    Code in those assemblies cannot call code from Assembly-CSharp_resident code, so there's no cyclic dependency thing. Unless you mean between the other assemblies.
     
  34. hadrien_g

    hadrien_g

    Joined:
    Sep 29, 2014
    Posts:
    2
    Totally agree with rastlin about the project structure: it would be much more readable and easier to navigate by removing the redundant folders and only include folders from the json file level and beyond.

    Also, even the compilation time will scale better with this new structure, I notice it still takes 2-3 seconds to recompile even a small project with a few classes. Compiling the same project in VS only takes a fraction of a second. My understanding is that Unity also unload/reload the editor GUI and the game assets when recompiling, but is there any plan to improve the compile time further?

    Thanks and good job Unity team.
     
  35. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,713
    Thanks for the feedback!

    I revised the example project and removed the redundant folder.
     
  36. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    434
    When bringing TextMeshPro (the purchased source code version for 2017) into a clean project and using the assembly file, it throws an error in a bunch of files: "The type of namespace name 'UI' does not exist in the namespace 'UnityEditor'. Are you missing an assembly reference?". Any idea why this would happen? It works fine without the X.assembly.json file ... but the moment one is added to the project, it breaks as above.

    Edit: It has nothing to do with TMP. Create any new project. Add an editor folder, and an editor file with a "using UnityEditor.UI" line. This works fine. Then add an assembly.json file. As soon as its added, the above error is thrown.
     
    Last edited: Aug 2, 2017
  37. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    434
    If I add the UnityEditor.UI.dll to the project it fixes itself. I'm assuming this should be fixed internally.
     
  38. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    434
    Am I correct in understanding that if a project has 2 base folders (A and B), and only B has an assembly.json, then changing a file in A will not re-compile B (since B is essentially a seperate .dll), but changing a file in B will re-compile A (since A is still part of the generic non-assembly code)?
     
  39. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    Shouldn't. Folders and scripts that are not part of an assembly.json will eventually be compiled in Assebly-CSharp.dll.
    So if you change something in B then only B should recompile. If you change sometihng in A only the scripts under Assembly-CSharp should. Doesn't really make sense to say it improves compile times otherwise.
     
  40. DGordon

    DGordon

    Joined:
    Dec 8, 2013
    Posts:
    434
    From https://drive.google.com/file/d/0Bykxs2qcd6PSUTJhYkJySS1hazA/view

    "If a project is using .assembly.json files, it is highly recommend that they be used for all scripts
    in the project. Otherwise the scripts not using .assembly.json files would always be recompiled if
    any .assembly.json file is recompiled. And thereby reducing the benefit of using .assembly.json
    files."

    This is why I want a confirmation of this. I am trying to retrofit this onto something already built and its not so easy (my fault, it wasn't built in a way friendly to this), and I don't want to jump through any more hoops before I know for sure how this is working.
     
  41. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    In that case, the whole project structure has to change to reap the benefits. I get that if signatures are changing or stuff are added that callers from the main assembly will force a recompile to the main assembly too, but if it's a transparent change why should it?
     
  42. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    And how will the compiler know if it's a transparent change?

    It cannot, unless it compiles the main assembly. You are also doing it inside your head as well, when you make a change, you are scanning your dependant code and only after you do that, you know that "it's a transparent change" or not.

    It has always been like this in any compiler, once you change something down the dependency tree, you have to recompile everything up the tree - just in case the change downstream affects the upstream.
     
  43. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    But the API hasn't changed in a transparent change. The symbol tree should be the same at least up to the function signatures. If you change something that's ultimately in an inner scope but doesn't change the function signature which is what you end up calling in other assemblies why should it force the other assemblies to recompile? I'd understand relinking , since the byte offsets of the functions inside the library change due to a content change but not recompiling?
    Am I missing something?
     
    Last edited: Aug 5, 2017
  44. Dmitry-Pyalov

    Dmitry-Pyalov

    Joined:
    Dec 13, 2011
    Posts:
    83
    @jbevain
    Updated VSTU's from this post don't work with Unity 5.5
    2017-08-11_22-12-36.png
     
  45. jbevain

    jbevain

    Microsoft

    Joined:
    Feb 22, 2012
    Posts:
    136
    That's not unexpected, the beta build provided above is just for 2017.2 betas.

    Thanks for reporting it that being said :)
     
  46. Dmitry-Pyalov

    Dmitry-Pyalov

    Joined:
    Dec 13, 2011
    Posts:
    83
    By the way.
    MSDN reports that VSTU is already released in the future :)

    Has anyone been there (in the future), is it really released on August 14? :)
    2017-08-13_19-30-30.png
     
    Harinezumi likes this.
  47. Dmitry-Pyalov

    Dmitry-Pyalov

    Joined:
    Dec 13, 2011
    Posts:
    83
    Quatum1000 likes this.
  48. zhuxianzhi

    zhuxianzhi

    Joined:
    Mar 30, 2015
    Posts:
    36
    How do I manually specify an assembly? I used UnityEditor.Graphs in my code, but the generated .csproj was not included and I tried to specify it in the reference array and could not work
     
  49. HonorableDaniel

    HonorableDaniel

    Joined:
    Feb 28, 2007
    Posts:
    2,855
    What happens if you have multiple identical Assembly Definition files in different folders?
    What happens if you have multiple Assembly Definition files in the same folder?
     
  50. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Did it just work when using "regular" scripts? Or did you have to perform some kind setup?


    An error will the emitted in both cases.
     
    HonorableDaniel likes this.