Search Unity

Assembly Definition files not working as expected.

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

  1. Lee7

    Lee7

    Joined:
    Feb 11, 2014
    Posts:
    137
    I am trying to use Assembly definition files, I create one and suddenly classes outside of that definition file are no longer able to see namespaces and classes inside of it.

    I hope this is not the intended behavior, as this this makes it quite useless IMO. So, I hope its a bug.

    Cannot seem to resolve it, any help would be appreciated.
     
  2. Lee7

    Lee7

    Joined:
    Feb 11, 2014
    Posts:
    137
    Yeah this is completely jacked up, there is no way this is desired behavior.

     
  3. Lee7

    Lee7

    Joined:
    Feb 11, 2014
    Posts:
    137
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    That's not been my experience.

    Are the files that can't read the files in their own assembly definition, or are they just free-floating scripts?
     
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
  6. Lee7

    Lee7

    Joined:
    Feb 11, 2014
    Posts:
    137
    I did that, but it seems to be making no difference. I tried referencing in both directions, its got to be a bug.

    I also get different results:

    1) If I create the asmdef files in different orders.
    or
    2) if I make the assembly definition files, close editor, delete the sln and csproj files, reopen editor.

    I can sometimes get two asmdef's to play together nicely, but 3 or more never work. Always one definition file will not be able to "see" others.

    I even did a layout exactly like described in https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html
     
  7. Lee7

    Lee7

    Joined:
    Feb 11, 2014
    Posts:
    137
    Both. The 2nd screenshot I posted was simply creating an asmdef in the "ThirdParty" folder. No other asmdef files were in the project.

    The first screenshot was with a "Main" asmdef file located in the root assets folder. If i ONLY create this file, it works. But then when I add another one elsewhere, suddenly unity doesnt see my scripts as monobehaviours anymore.

    I have played with it for 4+ hours, playing with references, moving folders around, etc. Cannot get it to function as expected.
     
  8. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Can you share a simple project to show the issues you are having?
     
  9. BigToe

    BigToe

    Joined:
    Nov 1, 2010
    Posts:
    208
    Having similar problem too with an assembly definition file in a ThirdParty folder and Editor folders. Works fine in the editor, but throws all sorts of errors when attempting to build to iOS.

    I get 212 Errors similar to this:
    Assets/ThirdParty/EasyTouchBundle/EasyTouch/_Documentation/Cinemachine/Base/Editor/Editors/CinemachineBasicMultiChannelPerlinEditor.cs(3,7): error CS0246: The type or namespace name `UnityEditor' could not be found. Are you missing an assembly reference?

    Not sure if I should be removing the Standard Assets folder, or adding a Main assembly definition file, or removing all the editor folders from the Third Party folder? I tried excluding for iOS, but that wasn't the answer.
     
    KarolRG, leni8ec and WayneC like this.
  10. Lee7

    Lee7

    Joined:
    Feb 11, 2014
    Posts:
    137
    My project is pretty huge, its an in progress game and I also have a few Third Party assets that are really large MB wise that I haven't cleaned up. Whats the process for sharing stuff like that?

    I might be able to replicate the issue in a blank project. Regardless, if the issue is not occurring in a new project, it doesnt matter because it exists in a more complete project.

    EDIT: I will delete sounds, textures and meshes to make it smaller. How do I need to send it in?
     
    Last edited: Jan 5, 2018
  11. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Check karl's sig!
     
    karl_jones likes this.
  12. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    When using asmebly definitions you need to also define what is an Editor assembly. Editor folders are not treated as special folders. So add another assembly def file into the Editor folder and set it to be Editor only. Then tell it to reference the other assembly so it can see the contents. https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html
     
  13. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    If you can create a really simple one with a few scripts that would be idea. I suspect its just in the way you have set up the asembly files. You can submit a bug report if you think its a bug or just upload it here if its small enough and I can take a look.
     
  14. steffen-itterheim

    steffen-itterheim

    Joined:
    Nov 10, 2015
    Posts:
    24
    Could we have a checkbox under "Any Platform" that reads "Editor only"? So that when you click "Editor only" it will deselect "Any Platform" as well as all other platforms except "Editor".

    Because right now the workflow for an Editor asmdef is:
    • Create Assembly Definition in Editor folder
    • (wait for recompile)
    • Uncheck "Any Platform"
    • Click "Deselect all" at the very bottom
    • Click "Editor" at the top (2nd item)
    • Apply
    • (wait for recompile)
    Just feels unecessarly convoluted, especially since you have that convenience when assigning platforms to DLL files dropped into the project.

    Happened to me quite a few times that I missed the "Editor" checkbox too and selected another platform instead. In a project where compiling then takes 10 seconds or so it's particularly annoying.

    Or why not use the existing Inspector for DLLs. Wouldn't that work?
     
    Last edited: Jan 12, 2018
  15. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    So I was thinking about setting this up in my project, but it seems like it might not be as magical as I initially thought. Am I right about this process?:

    1) Create asmdef in the base directory (catch all).
    2) Add asmdef files to every Editor directory.
    3) Add asmdef files in subfolders as you see fit, but if classes within that subfolder reference another folder, you need to link those.

    This means we need to edit asset directories, right? Rather than a catch all in the base directory working for important assets? It also means it's not trivial to have an asmdef in my game's directory, as I need to update it with every asset's directory wherever they're referenced.

    Or am I understanding this incorrectly?
     
  16. steffen-itterheim

    steffen-itterheim

    Joined:
    Nov 10, 2015
    Posts:
    24
    Assembly Definitions only affect .cs files. Ignore assets, they have nothing to do with assemblies (assembly == "DLL" ... more or less).

    I changed the file structure in my projects so that I have:

    Scripts
    Scripts/SubfolderPerFeature
    Editor
    Editor/SubfolderPerFeature


    The former way of doing things did not lend itself well to adapting to asmdefs, meaning I would rather avoid this structure from now on:

    Scripts
    Scripts/SubfolderPerFeature
    Scripts/SubfolderPerFeature/Editor


    Assembly definitions work better/easier if you can start out with 2 asmdef, one under /Scripts and one under /Editor, rather than having to check every Scripts subfolder for an Editor folder and having to reference that.

    Once I have this, I start decoupling individual features. The idea is that eventually the asmdef in /Scripts and /Editor will be declared "DO NOT USE" and no .cs file should belong to them. To ensure that, I eventually switch off all platforms except for one we will never ever use (Tizen ... WTF is that anyway? *g*). That way all new features will have to have an asmdef.

    In the end you have about the same work with both structures, but there's one big reason to avoid Editor subfolders:
    • Programmer creates new "feature" folder with scripts in it
    • Programmer creates asmdef for that feature
    • all is fine up to here
    • Programmer adds some "Editor" scripts to this feature-folder
    • Programmer does not add asmdef for Editor
    • all seems fine but .... from now on builds will fail
    The reason is that asmdef by default include "Any Platform", which includes editor. So the above workflow will tend to create asmdefs that include Editor scripts which of course can't be in a build.

    Therefore separating Scripts and Editor in two folder paths makes it clearer that one needs to create an asmdef for both. And even if you forget to add an asmdef, the "catch-all" asmdef at the Script or Editor root folder will get these script files and thus builds continue to work. It's only at the time where you need to reference a new feature in some other asmdef that you'll find that this feature you're trying to reference has no asmdef yet, so you'll add one.
     
    Last edited: Jan 15, 2018
    OnatKorucu, masterton, Rrawrr and 4 others like this.
  17. gumboots

    gumboots

    Joined:
    May 24, 2011
    Posts:
    298
    Thanks for the explanation! Though by 'Assets' I mean scripts downloaded from the Asset Store. They always have their own folder/file structures, so you now need to add asmdef files to them, or restructure them like you've suggested. But that seems like a nightmare for upgrading?
     
  18. steffen-itterheim

    steffen-itterheim

    Joined:
    Nov 10, 2015
    Posts:
    24
    Contact the developer and encourage him/her to provide asmdef with the next release (I suppose these files will be ignored if the user uses an older version of Unity).

    During the transitional period we have to do this ourselves. However I rarely need more than 10 minutes to prepare an Asset Store plugin for general release among our developers, including cleaning up file structure and suppressing warnings (sometimes even errors). Plus upgrading plugins is something we only do when we are convinced that it helps our work. Over the year we upgrade each plugin on average once or twice.
     
  19. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    519
    I'd like to get back to the subject of the post.

    Having the same issue with my 3rdparties when trying to create a thirdparty.dll, mostly my regular main scripts (that will be added to Assembly-Csharp.dll don't get to know what's inside the thridparty dll.

    My third party folder is not under the unity Script folder. Could it be something ?

    upload_2018-3-10_10-48-37.png
     
  20. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    519
    - Allright, so then I simply moved the assembly definition file into a single submodule (TextMeshPro in this case)

    Now it compiles. Why ? Any clue ?
     
  21. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    519
    Could you tell from your side why are we having this behavior? It seems I almost got it working finally by manually adding an assembly definition file in every third party module that was not recognized by the main .dll

    It's a definitely tedious as most third party asset does not have an assembly definition file. Plus it's not the intended behavior, feels buggy.

    Those errors should not be there, I quintupled checked.

    upload_2018-3-10_19-42-16.png
     
  22. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    519
    We managed to have it working, beware to check that there is no assembly reference error in the first line of your console ( EConsole was not showing it)
     
  23. joebain

    joebain

    Joined:
    Oct 24, 2014
    Posts:
    49
    I have been having this problem and I just solved it (for me at least). The errors are pretty unhelpful because I think what they really point to is there was an error compiling the assembly which should contain the namespaces or classes which can't be found. In my case I had a lot of errors saying "PostProcessing" namespace couldn't be found. The actual problem was that my "Plugins/" directory, which has it's new asmdef file, was not compiling and so not producing a dll with the PostProcessing classes. The reason the "Plugins/" directory was not producing a dll was because there was a subfolder in that directory with some Boo files in. Once I put a separate asmdef file in with the Boo files, then everything else was ok.

    I definitely think the error messages could be improved here, by pointing out the first assembly which failed to compile, rather than the error messages from the compilation of the final .exe. And obviously there should be an error when folders mix script types.
     
    chadfranklin47 and Arkade like this.
  24. Whatever560

    Whatever560

    Joined:
    Jan 5, 2016
    Posts:
    519
    Same happened to me with .js files (error appeared in the console at some point). Also +1 for better error feedback
     
  25. StephenHodgson-Valorem

    StephenHodgson-Valorem

    Joined:
    Mar 8, 2017
    Posts:
    148
    Anyone else notice the duplicate projects in the solution with the *.Player on the end?

    What's that about? I only see them pop up after I've switched build targets.
     
    Last edited: May 4, 2018
  26. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Hi Karl,

    I wonder if you could clarify something for me. I have a "ThirdParty" directory in which I've placed all of the 3rd party packages I use in my project. To isolate that code, I've added an Assembly Definition file at the root of the ThirdParty directory.

    Almost all of these 3rd party packages have their own Editor directory. Is the recommended/required approach that I got into each of those Editor directories, and create an editor-only Assembly Definition, which references my ThirdParty assembly definition? That seems to be what I need to do in order to avoid build errors. But it also seems awkward to have to add content to a 3rd party directory. What if I update the package? Do I need to go around updating assembly definitions each time I do this?

    This is made worse by the likelihood that any given 3rd party package will have many different Editor folders within each, each of which seem to need a separate assembly def file. I assume I must be doing something wrong...
     
    Last edited: May 7, 2018
    NEVER-SETTLE likes this.
  27. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Yes that's what needs to be done. If you want to use the Editor folder approach then either set up the assembly files or don't use them so it reverts back. Third party packages such as those from our package system should be using assembly definition files and have it all set up for you.
     
    dgoyette likes this.
  28. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Thanks for the clarification. Maybe I'm just at an awkward point being on 2017.3 and using packages not sourced from the package manager. Sounds like things will be easier moving forward. Thanks again.
     
    karl_jones likes this.
  29. bonzaiferroni

    bonzaiferroni

    Joined:
    May 26, 2016
    Posts:
    30
    This seems broken with the release of the new Package Manager. If you import a package like TextMeshPro through package manager, the code is outside of your Assets folder. That means you can't solve the problem by placing an assembly definition file. Is there another way?
     
  30. Deleted User

    Deleted User

    Guest

    @karl_jones Just wanted to ask how you suggest to work with ASMDEFs when dealing with platform specific MonoBehaviours? The way it worked so far was to use preprocessor directives to compile them out, but you always left the class body intakt to not remove it as a reference from scene GameObjects to avoid warnings.
    If I now would just put all those scripts into an assembly for a specific platform and build for another one, all of them will be missing on GameObjects. Since GOs cannot be platform specifically removed, that's a problem.
    Not to mention SerializedFields.
     
  31. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Not sure I fully understand. If you only want scripts for certain platforms you could put them on objects that get loaded if they are required. E.g Resources.Load or through Addressables. I'd probably use Addressables.
    Also asmdefs are optional, if it doesn't fit your purpose then maybe don't use them
     
  32. Deleted User

    Deleted User

    Guest

    Even the following Unity link referencing Resources states "Don't Use it". By Adressables, you mean AssetBundles?
     
  33. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
  34. summerian

    summerian

    Joined:
    Jul 6, 2014
    Posts:
    140
    How do we use this with assets inside the Package Manager?

    When I create an assembly definition for my own scripts I get the error
    • The type or namespace name `TMPro' could not be found. Are you missing an assembly reference?

    And I can't add a reference to TMPro in the Package Manager.
     
  35. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    You just drag the reference in. Like so:
    example.gif
     
  36. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    I don't have the Packages entry in my Project view. Is that new in 2018.2, or am I missing something?
     
  37. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Yes its new in 2018.2
    You can also manually edit the asmdef file.

    e.g
    Code (CSharp):
    1. {
    2.     "name": "NewAssembly",
    3.     "references": [
    4.         "Unity.TextMeshPro" //<<==== ADD THIS
    5.     ],
    6.     "optionalUnityReferences": [],
    7.     "includePlatforms": [],
    8.     "excludePlatforms": [],
    9.     "allowUnsafeCode": false,
    10.     "overrideReferences": false,
    11.     "precompiledReferences": [],
    12.     "autoReferenced": true,
    13.     "defineConstraints": []
    14. }
     
    StephenHodgson-Valorem and Baste like this.
  38. Deleted User

    Deleted User

    Guest

    @karl_jones I found a concrete case I like to hear your opinion about. I have a gameobject in my scene which is mandatory to be there. It reacts to UWP inputs. I now want to add android specific inputs without altering the code already written. For this to work I wrote an adapter that translates input from android to UWP. It has to exist on the gameobject. It's one of several scripts that are only needed on Android target platform. Now the thing is, I'd like to put all of these android scripts into their own ASMDEF. Problem is that it's attached to the gameobject and will result in a missing class when built. I could programmatically add it, but then I'll have to write yet another script to attach it and have that script in another ASMDEF which references the android one.
    How would you solve, or how would you handle such a situation?
    The simplest way would be an automatic component removal or hiding (in editor) if the component won't be available on that platform even though it exists in the editor (Would be a nice feature thinking about it. Greying out components that won't be part of the build, also showing what platform they're ment for or something similar).
     
  39. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    I would probably do something like a scriptable object delegate pattern(see the youtube video Richard Fine did at Unite)
    Then you edit the scriptable object instance, not the GameObject. My answer before regarding resources or addressable still applies as well.
    If something is platform specific then is it appropriate to have it in the scene attached to a GameObject when its only used on some platforms, is that not misleading to other developers who don't know its a special component?
    Would it not be better to have per platform assets in a platform directory so its clear what the purpose and platform is.
    Automatic component removal is something you could add as a custom build step if its something you really need for your project.

    Another alternative is to use preloaded assets. Add your platform-specific ones during the build step(we do it ourselves for some packages).
    E.G When building in the preprocess build step, add the platform-specific Prefab/Scriptable Object instance to the player preloaded assets field.
     
  40. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    Could you maybe consider actually documenting this feature? Afaik, since 2015 the only information available is the one from the manual about the standalone player settings, which says:
    "Set an array of assets to be loaded when the player starts up."

    There are a bunch of important information about how to use it, differences between the editor and players, etc. that are missing. A good example is that there's no information about how you'd go about using the platform-specific ScriptableObject you're recommending to use. It's preloaded, sure, but that doesn't help anyone get any information from it.

    I happen to know that OnEnable is called on application startup on ScriptableObjects added to the preloaded assets, and you can use that to assign it as a singleton. I don't think that's been written down anywhere.
     
    Mikael-H likes this.
  41. Deleted User

    Deleted User

    Guest

    @karl_jones I have another question related to ASMDEFs. Code is available to all platforms by default. If you don't like them on specific platforms you have to use preprocessor directives. What is actually missing though is an option for platform specific editor code.
    If the code is not platform specific in the case it does only run there, but in the case it is not needed in the game on other platforms, code still has to exist in the editor to be tested. This means that every ASMDEF containing scripts of this kind, has the target platform AND editor. But editor means its available on every platform. This means ASMDEFs are somewhat unusable here because you still have to go into the scripts and wrap them in #if UNITY_EDITOR && <Platform> to get that kind of combination.
    Is it possible to add this feature to ASMDEFs? Platform specific Editor ex-/includes?
     
  42. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Could you add your suggestion to https://feedback.unity3d.com/ then I can pass it on to the team.
     
  43. Deleted User

    Deleted User

    Guest

    Last edited by a moderator: Aug 2, 2018
    karl_jones likes this.
  44. Deleted User

    Deleted User

    Guest

    @karl_jones could you tell me if it's intended behavior that a lot of my ASMDEFs generate a second VS project file, ending on .Player.csproj
     
  45. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Intended. An assembly is its own project, this is how Visual Studio works. If they were all in the same project then visual studio would see them incorrectly(e.g internal properties would be visible when they should not be).
    An asmdef means that those scripts go into a separate dll, each dll needs its own project.
     
  46. Deleted User

    Deleted User

    Guest

    I got that alright. what I mean is that some of them appear twice, once with and once without the .Player addition to the name.
    in those cases, when searching references in code, both of these show their results even though they seem to be the same. and its not all of them. the editor Assembly files don't generate these twins at all.
     
  47. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,299
    Oh
    Hmm I'm not sure. It's worth filing a bug report.
     
  48. Deleted User

    Deleted User

    Guest

    Ok you guys,
    after a lot of back and forth I decided to roll back to not using ASMDEFs at the moment.
    Therefore I wrote something I wanted to share with the community, a Helper for toggling them to not loose your work. This package adds the following:

    - an ASMDEF menu to the top for toggling all ASMDEFs in the project Assets hierarchy
    - a context menu for ASMDEFs in the project view to block them from being toggled

    what it does is adding the ~ to the files so they disappear from Unity's AssetDatabase but can be added in again. For the files that are ignored a scriptableobject is created which lists the file names without extensions so you can easily see which ones are still active.

    Enjoy
     

    Attached Files:

    Last edited by a moderator: Aug 28, 2018
  49. ifisch

    ifisch

    Joined:
    Jul 15, 2012
    Posts:
    35
    Jesus Christ, why is the default behavior not to skip over /Editor/ folders?

    I, like many people, have my add-ons all in one folder. It would be great if I could just make an assembly for them all, but, as was stated above, many of them have one or multiple /Editor/ subfolders.

    If I tried to make an separate assembly definition for every single one of those would end up dozens if not hundreds of assembly definition files.

    Thanks for nothing.
     
  50. ifisch

    ifisch

    Joined:
    Jul 15, 2012
    Posts:
    35
    Or, at the very least, have the option to ignore the assembly definition file completely when I make a build. At least then my recompiles when using the Editor would be fast.

    Very disappointing.