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. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    945
    Tried creating assembly definition files from scratch in an empty project. Turns out, MonoBehaviours are not recognized as such in some assemblies, it is not possible to attach them if they are in a defined assembly. Once it's moved outside, it works fine.
    upload_2017-8-18_12-47-25.png
    Bug report case #943090.

    Also, is there going to be an API for this feature? It is important for code generation tools that run from within Unity. Parsing JSON files just to get a list of assemblies sounds like a waste of time.
     
  2. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    Does the solution get generated with three projects?
     
  3. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    945
    Just two, since the only code in the project is under folders controlled by .assembly.json files. If I create a script outside of these folders, then yes, a third project is created.
     
  4. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    I just tried reproducing the same project as you. But I had no MonoBehaviour issues whatsoever and I also have them both attached to the Camera in a test scene.

    I only get solution generation issues and only when I'm using VS2017. The Built-In MonoDevelop produces the solution properly.
    Reported the bug(case 943509) since it's probably a VSTU one. The error I got tried to create the project solution(basically what will eventually become Assembly-CSharp.dll) but since no script exists for that, there shouldn't be a need to generate one. Also no Bar/Foo projects get generated. The assembly def files only have the name inside so I doubt it's a json validation issue.
     
  5. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    945
    Yep. That's a different bug, I've already reported it as well (943090). If I just rename any folder that has an assembly definition file, that assembly definition is not reloaded, and an assembly with default name is generated instead.
     
  6. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    It seems like this happens due to some Library inconsistency. Some stuff might be cached and while the next time you hit the Open C# Project menu , the whole solution should regenerate from scratch, it seems to retain the default project. If on the other side, you dirty the assembly def file in question, like rename it and remove one character prior to the .assembly.json, it seems to properly regenerate the Foo and Bar projects.

    UPDATE: After the solution has been changed to keep the default assembly named project, instead of renaming the affected assembly def, you just reimport it, and then hit Open C# Project, it seems to work as well. It won't ,however, work if you only switch focus to MonoDevelop after renaming the folder and reimporting the assembly def. It seems like the system is content since there's a project with the default name and doesn't pursuit total cached data validation.So you need to hit the Open C# Project to cause the regeneration of the solution.

    @jbevain Is this a bug or default behaviour?
     
    Last edited: Aug 22, 2017
  7. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    I'm unable to reproduce this issue with the MonoBehaviours not being recognized when importing your project. The steps you took to setup this project to get to this state could be helpful. There might be an case we missed where the script is not being properly imported when changing the assembly definition files.

    Yes, there will be an API for this feature where you can get all the assemblies and their dependencies in the project.
     
  8. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    423
    This extra file is really, really weird to me. I didnt expect this to work like this, its so counter intuitive. Even with an editor for it it clutters up the project so much to have one of these files everywhere. Why not simply one assembly file in the project root? Perhaps it could be some option in the JSON structure to assign assemblies for child folders etc, so we can just have one single `root.assembly.json`.

    The folder .meta data seems perfect for this, it is metadata after all. Not looking forward to having this all over the place. The extension is a bit weird to me too, and i dont think ill name the file after the folder. In that case when we rename the folder we also have to rename the file. 'assembly.assembly.json' is super weird, so we'll have to get creative.

    What type of third party tools are you thinking about? Would it really be that weird to tell them to open the YAML file, that is how XCode project generation work too (and, granted, is a PITA). How many people are going to use/make these tools vs how many people just want to define an assembly.

    Maybe for third party tools they can extract this information by starting the editor headless, with an -dump-assemblies option that writes to stdout the information (unix style!). This way you can store the info in any way you want and represent it differently. That sure does sound easier for third party tools then to scan the entire folder for .assembly.json files and interpet them according to the Unity standard, including what to do when there are multiple files etc. Heck, you could even ask the Editor to just give you a string to pass to the compiler, or tell it to compile in the first place.

    I'm sure you guys have had a lot of discussions about this as well, just want to add my two cents.
     
    Last edited: Aug 22, 2017
  9. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    You do not need to rename the assembly definition file if you rename the folder. The assembly definition filename and folder name are independent of the assembly name specified inside the file.
     
  10. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    423
    I understand, and i would discourage anyone from naming it after the folder (as is done in the example). Because that means you'd want to rename the file when you rename the folder, something people are really going to forget.

    Instead i'd call them all something like 'def.assembly.json', but thinking of a good name is difficult.
     
    Last edited: Aug 22, 2017
  11. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    I don't particularly mind this. Especially since I've had to mess with a whole more things to get a solution regenerated properly with external project attached to it every time using ProjectGenerationHook and extra stuff to handle assembly replacing when a new build happens etc etc etc.This is a simpler solution for me anyway.

    I can see though the appeal of having a single file to specify how the assemblies will be instead of multiple. And since this is still WIP, things might change.
     
  12. Jes28

    Jes28

    Joined:
    Sep 3, 2012
    Posts:
    420
    Hi

    How we can use new assemblies with old style editor folders?
    So if I have for Example NGUI and want to pack it into separate asembly what I nned to write inside DefinitionFile in root folder of NGUI?
     
  13. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    For any Editor only folders you need to add a assembly definition file inside that folder and set includePlatforms to "Editor".

    If you add a assembly definition file in the root folder and have other assembly definition files in subfolders, then the subfolders scripts will not be included in the root folder assembly. This scenario is also described in the doc.
     
  14. Jes28

    Jes28

    Joined:
    Sep 3, 2012
    Posts:
    420
    I think I missed some thing.

    I can not find any documentation about assembly definition files nor manually not through search.

    And adding such file inside each editor filder result in error:
    Assembly with name 'MyAssetsEditor' is already defined


    Can you point me to docs of ADF and may be explain how i can add all Editor folders of package to to some EditorAssembly?

    May be instead of adding tens of separate ADF into each Editor folder it will be better to just add Option like "RespectEditorFolders" = "True" to Root ADF to simply mimic current behavior of Editor folders?
     
  15. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    npatch likes this.
  16. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,379
    Are the valid includePlatforms values the same as the ones defined in the BuildTarget enum? Or is this a different set?

    Once this is in, you should probably start recommending/demanding that asset store publishers put all of their code in one or more assemblies. That'll keep things clean and consistent.


    Oh, and another question! Right now, if you have any script compilation errors when you boot Unity, all editor windows will fail to load (I think).

    Would it be possible to load editor windows if their assemly compiles, even if some other assemblies the editor windows rely on don't compile? This mostly happens when you're opening the project in a new version of Unity, and there's something the auto-updater can't catch.
     
  17. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    The values for includePlatforms are names based upon the BuildTarget enums. If you put in a random name, an error will be printed which lists all the platform names. There will be an API to retrieve the platform names.

    Regarding loading of assemblies. We have changed it in 2017.2 so that any managed plugins and already compiled assembly definition file assemblies (which also have all their dependencies compiled) will always be loaded upon startup, even if there are compile errors in other (Assembly-CSharp) scripts.
     
    JoeStrout, npatch and Baste like this.
  18. jrhtcg

    jrhtcg

    Joined:
    Jul 13, 2013
    Posts:
    34
    When I convert an existing project to use this, the prefabs and object in my scenes are missing a reference to the various scripts that are now in their own DLL. Is there a way to tell which scripts that the missing references used to point to? I am looking for a way to fix the missing references without losing any of the data that has already been associated with a specific script?
     
  19. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    I did similar activity when I migrated my project, but I had my scripts in external dll's. So the activity on my part was to locate all files which had reference to the script in dll, and replace the fileID and guid to new ID. Unfortunately it was a manual labour, but it did not took long, since I did not had that much Assets which ware using scripts (maybe 50). Obviously you need a asset meta to be saved in text.

    As for your situation, not sure why this would happen. The scripts that are compiled under assembly definition files, are still treated as an individual files, they aren't referenced in your prefabs from dll, but individually. Maybe for some reason their guid's has been re-generated. I guess only way for you to fix this, is to edit each prefab individually and update the guid references for your scripts:

    m_Script: {fileID: 11500000, guid: a14081b2064149c47b4e54c6a50a6a3c, type: 3}

    You can check the new guid in meta file for your script.
     
  20. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    I've made a note a this scenario and will look into whether we can do anything to make this upgrade easier.
     
  21. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    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.
     
  22. bwheatley

    bwheatley

    Joined:
    Jun 23, 2012
    Posts:
    44
    Thanks for the update, yea i'm having a heck of a time getting it to work properly. <3 Danka
     
  23. ZimM

    ZimM

    Joined:
    Dec 24, 2012
    Posts:
    945
    Oh, that's a shame :( Perhaps it can be just marked as Experimental in 2017.2 and come without the editor integration? So at least advanced users could try it out in real projects then.
     
  24. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    112
    Personally I had little troubles migrating my own assembly - based project to this new structure and have not yet encountered any issues.

    So I second ZimM's request, would be nice if we could have this as experimental in 2017.2 :) .
     
  25. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    The assembly definition files feature has been completely disabled in 2017.2.0b11 and will not be made available as an experimental feature in 2017.2.

    It will however be available from 2017.3.0b1 with complete editor integration.
     
  26. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    171
    Hi guys,

    Developer of Odin Inspector and Serializer here. Just had a few issues reported related to this feature in 2017.2. I understand it's been postponed to 2017.3, so it seems there is time for me to make a small feature request. Right now it is very difficult for us to reliably detect whether a custom user-defined script assembly is, well, a user-defined script assembly.

    Our best bet seems to be checking whether the assembly is located in the project's ScriptAssemblies folder, but this doesn't seem to be a very good solution, since it will not work in builds. For Unity's own "hardcoded" user script assemblies, we have so far just relied on the naming, which has worked out fine, but that doesn't cut it here either, for obvious reasons.

    Would it be possible for you to decorate all custom user script assemblies with an attribute, like a UnityEngine.CustomUserScriptAssemblyAttribute, or do something in a similar vein? That would make it a lot easier for plugin developers to detect whether any given assembly is user defined or not.
     
    Last edited: Sep 9, 2017
  27. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    There will be an API for retrieving the whole "assembly compilation graph", will this solve your issue?

    It currently looks like this:

    Code (CSharp):
    1. public static Assembly[] CompilationPipeline.GetAssemblies()
    Assembly looks like this:
    Code (CSharp):
    1.  
    2. public class Assembly
    3. {
    4.     public string name { get; private set; }
    5.     public string outputPath { get; private set; }
    6.     public string[] sourceFiles { get; private set; }
    7.     public string[] defines { get; private set; }
    8.     public Assembly[] assemblyReferences { get; private set; }
    9.     public string[] compiledAssemblyReferences { get; private set; }
    10.     public AssemblyFlags flags { get; private set; }
    11.  
    12.     public string[] allReferences { get { return assemblyReferences.Select(a => a.outputPath).Concat(compiledAssemblyReferences).ToArray(); } }
    13. }
     
    codestage and npatch like this.
  28. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    171
    That looks like an editor-only API, in which case, it seems about equivalent to checking whether the assembly is located in the ScriptAssemblies folder (albeit probably a better way of doing it - so thanks for providing that! :) ).

    Is that API available at runtime? We don't strictly *need* this at runtime, but it would be very nice to have a way of telling user assemblies from the others, to keep our assembly utility APIs consistent between the editor and a runtime build. That's always a recipe for problems.
     
  29. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Yes, this is an editor-only API as it is dependent on the compilation pipeline which is not available at runtime. For consistent behaviour across the editor and runtime I suggest serializing the assembly info in InitializeOnLoad and accessing the serialized data in both the editor and at runtime.
     
  30. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    171
    Very well. We probably won't do that, as it seems a solution worse than the potential problem it's solving. Thanks for the tip, though - we'll likely switch to using that API to solve the problem in the editor, once 2017.3 comes out.
     
  31. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    645
    Will assemblies output using this system automatically gain support for the iconMap for scripts that use custom icons (e.g. for components in the Inspector or assets in the Project view)?
     
  32. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    This feature has not changed how script icons are displayed, so I would expect this to worked the same way as previously.
     
    SonicBloomEric likes this.
  33. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    645
    The assemblies output by the system end up next to the assembly definition file, yes? If they end up in some other location as part of the output then the iconMap approach outlined here would be more complicated (or impossible?) to maintain.

    Would also be nice if the icon settings for a script (settable in the inspector) could be automatically picked up and ported into the output assembly...
     
  34. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    The assemblies are output to the LIbrary/ScriptAssemblies folder, just like the assemblies for regular scripts.
     
  35. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    645
    Ahh. Hmm... Perhaps it just works, then?

    Do you happen to know how the built-in UnityExtension DLLs (e.g. the new Unity UI system) are assigned icons in the Editor? There aren't any [visibly] associated .meta files so how the associations are maintained is somewhat of a mystery. It would be very nice to maintain icon asset associations for Editor tools...
     
  36. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Unfortunately I don't know how the icon assignment works. If you think there is some faulty or incorrect behaviour related to icons, I would suggest that you report a bug on the issue, which will get forwarded to the correct team.
     
  37. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    645
    It sounds as though they are loaded from built-in asset bundles and matched by namespace (supposedly the internal icons are named with the fully qualified namespace). In theory, placing a correctly named icon in the Editor Default Resources or possibly Gizmos folder might enable this. I have no idea if the system checks there but it's worth a shot. I'll see if it works with custom DLLs locally...
     
  38. SonicBloomEric

    SonicBloomEric

    Joined:
    Sep 11, 2014
    Posts:
    645
    Actually, I don't think the icons will be an issue for this feature. Icons for scripts that are compiled into ScriptAssemblies automatically are set on the script file itself (stored in the "MonoImporter.icon" field in the script's meta file). As these already work for the built-in method, presumably the icons (which are used within the Editor) should be associated to the Mono class by the MonoImporter for the C# script already.

    So everything should Just Work™.
     
  39. Rob-Fireproof

    Rob-Fireproof

    Joined:
    Dec 18, 2012
    Posts:
    18
    Did this feature make it into 2017.3.0b2? I've created some .json files as the docs describe, but it doesn't seem to have any effect (the Library/ScriptAssemblies folder just contains the regular set).

    I also tried the demo project linked in the first post and generated the scripts and assembly definitions, and that didn't seem to have an effect.

    Is there an over-riding on/off switch for the system I need to toggle? I can't see anything in the player settings.
     
  40. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,713
    Hi Rob,
    Thanks for bringing this to our attention! The project and documentation didn't reflect the latest changes yet. The file type of the definition files changed from .json to .asmdef. So the feature is indeed already included in 2017.3 but you have to change the file type of your definition files. I've updated the project and uploaded the new documentation.

    Project: https://oc.unity3d.com/index.php/s/xIUxflUSkbcipM8
    Documentation: https://drive.google.com/file/d/0B51Vmelt0rENZThZOTl5ZTIyN28/view?usp=sharing
     
    Last edited: Oct 2, 2017
    codestage, Rob-Fireproof and Peter77 like this.
  41. Rob-Fireproof

    Rob-Fireproof

    Joined:
    Dec 18, 2012
    Posts:
    18
    Awesome - thanks! That's working now. (Or, at least, it will once I untangle all of my dependencies...)

    This doc (which is linked from the 2013.3 announcement on the blog) is still out of date though: https://drive.google.com/file/d/0Bykxs2qcd6PSUTJhYkJySS1hazA/view

     
  42. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,713
    Thanks again! That's fixed too now.
     
  43. Rob-Fireproof

    Rob-Fireproof

    Joined:
    Dec 18, 2012
    Posts:
    18
    Quick bit of feedback from playing around with it on a large-ish project with lots of 3rd party stuff.

    First, it's a great feature that's going to save us loads of time, as well as enforcing sensible dependencies between the various bits of code in our projects.

    The main problem I found was that it didn't seem very good at deciding when to compile the assemblies. For example, if you set up the asmdefs and then hit Reimport All (or delete your library and restart), it completely ignores the asmdefs and builds everything into the regular Assembly-Csharp dlls. You have to manually re-import a cs file in each assembly to force it to rebuild that one. It also seemed to occasionally lose references between the asmdefs when restarting Unity.

    In the Inspector for the asmdef files, it'd be great to have a "Select/Unselect all" button. Setting up an Editor only assembly (which we have a lot of) requires an RSI-inducing level of clicks.

    In the end I had to give up as I couldn't get Advanced Inspector to play nicely with the system. I've let the developers know and they're going to have a look into it.

    It'd be nice if compiler errors explicitly stated which assembly it was trying to compile. I know you can select the cs file and that tells you which one that's in, but having it up front in the error message would be more convenient.

    As a longer term nice-to-have, some sort of overall "Script Assemblies" editor window showing all of the asmdefs and the relationships between them would be awesome.
     
    Peter77 and lukaszunity like this.
  44. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    This is a bug. The asmdef files should always be used and the references should not be lost. We will look into it.

    We will add a "Select/Unselect All" button.

    We will look into adding this.

    Currently there is C# API in UnityEditor.Compilation.CompilationPipeline for getting all the assemblies and their relationships. We will be looking into visualizing the relationships in the future.

    Thank you for taking the time to provide this feedback, it has been very helpful.
     
  45. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    Changes related to this feature for Unity 2017.3.0b5

    - Fixed issue where .asmdef files would lose references if their filename has multiple extensions (dots).
    - Added "Select all" and "Deselect all" buttons for platforms to Assembly Definition Files inspector
    - Misc minor fixes related to CompilationPipeline.assemblyCompilationStarted and CompilationPipeline.assemblyCompilationFinished API, see release notes for details.

    @Rob-Fireproof We have been unable to reproduce the "reimport all scripts compiles to Assembly-CSharp.dll and friends" issue, it might have been related to the lost references issue that was fixed. If you still experience this issue in 2017.3.0b5, then we would greatly appreciate a bug report with a repro project :)
     
  46. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,119
    Is there a property I can add at the head of a script to tell it in which assembly to exist?
    like [Assembly("VFX")]
     
  47. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
  48. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,119
    This is to define assembly within the code, keeps things nice and simple.
     
  49. lukaszunity

    lukaszunity

    Unity Technologies

    Joined:
    Jun 11, 2014
    Posts:
    434
    We will not support defining which assembly a script belongs to inside a script using attribute.

    Only the assembly definition files define which assembly a script belongs to.
     
  50. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    Code Generation cases? Though if you do that, you can also generate a json or whatever it is you want for the folder containing the generated code.