Search Unity

Example Project - Assembly Definition Files

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

  1. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    Thanks for sending that over! I'll post back with my results very shortly. I have not tried switching build platforms with that many assemblies, no -- I wound up culling the number of assemblies to more like 9 before doing that, and it was basically as fast as ever. The bulk of the platform-switching time is shaders and materials and other non-C# assets from what I can glean, so if there's an extra 10% (or whatever) time required to recompile all of the C# code compared to non-split assemblies, it would still be well worth it.

    For me in general, I tend to use Advanced Builder to just have it compile all of the platforms in sequence while I get a coffee or catch up on reading documentation or whatever. For asset bundles I have a specific set of code I put together myself that also profiles how long it takes (same time for lightmap baking), but the asmdef stuff doesn't affect those at all since they don't require platform context switches.

    On a totally random side note, I do wish it was possible to re-bake just all the reflection probes from code. For my scenes, typically static reflection probes are reflecting what the other static reflection probes are reflecting, which means that I have to do a normal lightmap bake pass plus reflection probe bake, then a second reflection probe bake manually from the lighting window. Not a crisis, but it's been interesting.
     
    guavaman likes this.
  2. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    I figure it's not worth clogging up this thread with discussions that are specific to Rewired. In general things are looking great and I love the folder structure you have there, though. I'm still getting the one error that is harmless but irritating, but I sent you some debug info by email. Cheers, and thanks for all the work. :)

    edit: Just in case anyone is wondering, the solution was simply "delete the entire Rewired folder and reinstall, and then it works fine." The GUIDs had gotten off for some reason on one of the folders in the tree. So all is well with yet another asset using asmdef files, and this is perhaps the very first asset to include its own asmdef files directly within it from the start -- really slick. :)
     
    Last edited: Nov 29, 2017
    guavaman likes this.
  3. Peter77

    Peter77

    Joined:
    Jun 12, 2013
    Posts:
    4,273
    Pressing "Assets > Open C# Project" causes Unity to stop responding (freeze) until Visual Studio finished opening the generated solution file. As the time to open that solution increases the more asmdef files are used, due to more .csproj files, are there any plans to fix the behavior that Unity stops responding while opening the solution?

    For me, Unity freezes about 30-40 seconds when I hit "Open C# Project" and that's without using asmdef's yet. As pointed out in this post, "a noticeable degradation in performance with 20ish dlls in a project" as been observed.

    I'm afraid "Open C# Project" is going to freeze Unity even longer when I start to use asmdef's.
     
    laurentlavigne likes this.
  4. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,134
    This bug happens with VS as well, the project file is either not updated (unlikely) or the signal to force update is not sent to those editor.
     
  5. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,487
    Tried using this stuff today. Completely unusable for the most part. Mostly because what I want assemblies for is third party stuff, and the current (bad) practice among asset developers is to have dependencies on other assets managed via ifdefs. That and mixed practices with Editor folders.

    What I thought this system was at first glance, is you created a definition that you named specific files in. Which while I realize maybe not as easy to setup, is the more correct solution if you look at how dependency management is done in most systems. You don't do it by folder for some of the very issues cropping up in this thread.
     
    mattnewport likes this.
  6. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    I can see advantages and disadvantages to both approaches.

    The folder approach allows things like I'm doing such as progressively adding new packs of C# files underneath a main .asmdef and having them automatically added to the assembly. Very easy for the user. Same with deletion -- just delete the file and it's gone. In a file list approach (like Visual Studio, etc), a script would have to be used to add/remove files from the file list which complicates things, especially deletion/removal of file packs.

    I do agree that the file list approach should be an option though because that is the standard way of doing things and would allow for much greater flexibility in very large projects. The list approach would have to use asset database GUIDs for tracking the files because paths would change every time someone moves files around.

    For the current folder-based approach, what I would like to see is for it to allow "partial" assembly definition files, similar to partial classes in C#. (Edit: I see this was suggested by @x4000 already here. After working with .asmdef's for a few days, I agree. +1.) As long as the assembly definition name is the same, anything other .asmdef files that share that same name get compiled into the same library. (Similar to the way sprite atlas tags work.) You would have the issue of managing the platform compile checkboxes in the inspector among multiple .asmdef files, but you could handle that the same way C# does by 1) (maybe) requiring the "partial" checkbox to be set when multiple share the same name and 2) throwing an error when more than one .asmdef file defines compile platforms, forcing you to set your platforms on only one (just like declaring class inheritance in C#). This would solve the issue with scattered Editor folders within an asset's folder tree causing many different editor assemblies to be generated. Perhaps even one .asmdef file could be designated the primary so the child ones would just automatically not display the compile platform checkboxes in the inspector and would inherit from the primary.
     
    Last edited: Nov 29, 2017
  7. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    282
    My main pain points were cascade compilations (that take much longer than if my entire project was recompiled) and solution loads/reloads.
    I tested on Rider and it is less insane than Visual Studio, but still much worse than just a few projects. The sad part is that Rider doesn't have a dedicated, "unity-aware" solution/project view (issue #106). Also, it has no "community" equivalent.

    I tested up to having about 100 projects total vs just 4 (LostAlloy, LostAlloy-Editor, Vendor and Vendor-Editor).
    For example, Full Inspector alone will add about 25-30 projects (lots of modules, each having its own Editor folder).

    At a certain point I thought I was going insane with how long compilations/reloads were taking and almost gave up on the asmdef idea. But, after converting to fewer assemblies it actually got much better than what I had before (I used the first-pass assembly as much as possible, but still had third party code in my assembly). When I was converting, I got up to compilation/reload sessions that took minutes, but even a full project recompile never crossed the minute mark. Cascading is no joke. Now I'm down to about 30s for the vendor assembly and about 10 for mine.


    I plan on testing again with lots of assemblies (with dependencies) at another time.

    I really like the "partial asmdef" idea from @x4000 and I hope it lands soon. This will make all this much more manageable for all of us.
     
  8. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    I see. That does sound like it could add up to a very bad situation if you have a lot of assets installed with addons like Rewired and Full Inspector... I don't really see any good solution at this point. The partial asmdef is ideal.

    I just realized another very bad situation for Asset Store developers using .asmdef files...

    If an asset has dependencies on another package and that package's classes aren't moved into an .asmdef file, the first will no longer be able to find those dependencies unless the user manually moves them into an .asmdef file and adds a reference to the other .asmdef file.

    Take this example:
    • Rewired + optional UFPS integration pack.
    • Rewired UFPS pack uses classes from UFPS scripts.
    • Because Rewired UFPS pack is extracted to a folder below the main .asmdef file, it is compiled to Rewired_CSharp.dll using the included .asmdef file in Rewired.
    • UFPS does not include an .asmdef file. All references to UFPS classes break. The user has to manually move UFPS's classes into an assembly and add a reference to UFPS .asmdef in Rewired_CSharp.asmdef.
    • The next time the user updates Rewired, Rewired_CSharp.asmdef is overwritten and they are met with the same compiler errors as before.
    Managing dependencies between assets is going to get a whole lot more complicated... I really hate to do this, but I'm going to have to backtrack and remove the .asmdef files from Rewired. I cannot have users forced to add their main assets into .asmdef files just so Rewired's assembly can find them. Unless I'm missing something, this effectively rules out bundling .asmdef files with an asset that may have any possible external dependencies like Rewired. Or at the very least, it requires a different structure to keep classes with external dependencies out of the assembly. This is going to have to be a manual process by the user, which means they will be moving files all over the place making it nearly impossible to update the asset...
     
    Last edited: Nov 30, 2017
    noio and SugoiDev like this.
  9. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    282
    > If an asset has dependencies on another package and that package's classes aren't moved into an .asmdef file, the first will no longer be able to find those dependencies unless the user manually moves them into an .asmdef file and adds a reference to the other .asmdef file.

    Oh, that's an important case I hadn't thought about yet.
    I think removing the asmdefs from Rewired is the best choice for now.
    This seems like one of those things that either everyone is in, or no one can safely be in.

    If you go with the idea of keeping the classes with external dependencies out of the assembly, those classes themselves would not be available to Rewired and you would have to have them binding themselves to Rewired. Also, anything that isn't in a custom assembly gets recompiled when any custom assembly recompiles, so the value of custom assemblies diminishes the more stuff is not a custom assembly (that's a lot of custom assemblies in a single sentence!).

    A possible alternative would be to detect the presence of the assets you want integrate with, and add your own binding script in their main folder. The binding script should bind anything you need into Rewired. But, that's a hell lot of work. I'm doing it, but with only one or two simple methods (custom logging). Of course, this would break if the asset itself used its own custom assembly, so this whole idea is probably not very good.


    About updates having moved files around: as long as the meta remains the same, Unity has been nice dealing with it. The main issue is with added assets. Those will go into their "canonical" folders. For example, I moved Rewired's main folder. When a new hardware map is added, a new HardwareMaps\Joysticks\ folder is created with those newly added maps. I have to manually move them over to their correct folder and delete the newly created ones.
     
  10. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    One of the things about NOT having asmdef files in an asset, though, is that then the asmdef files of the developer can't reference them. I have a variety of code that references Rewired that is in my own asmdef files, but if I don't have Rewired in asmdef files then I can't use asmdef files of my own. Compile times were approaching 30s for me prior to asmdef, but now I get under 8s most of the time, with most of that being editor-reloading-namespaces time.

    If Rewired doesn't have an asmdef in it by default, that's perfectly fine with me, so long as I can leave it in the same location and put in asmdef files like you structured it in your most recent builds. Having it looking in those asmdef-based dlls and finding the classes it needs was a godsend and works perfectly. I don't use UFPS or any of the other third party plugins that Rewired hooks into, but if I did I'm the sort who would be okay with putting in manual effort to get them working across asmdef lines.

    So long as I CAN get it working, I don't mind if it's a pain. What I mind is if there's something in the compiled Rewired dlls that I can't get working no matter what I do.
     
    guavaman likes this.
  11. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    Hoooooly cow. I just started using the VS 2017 15.5 preview 5 build from Nov 29th, which you can see and/or download here: https://www.visualstudio.com/en-us/news/releasenotes/vs2017-preview-relnotes

    The new VSTU behaviors in there are no joke. I tested this out with moving a few files between projects, which normally was requiring the "things have changed -- reimport everything in the solution?" prompt... and then was normally taking a while for it to unload and reload every project and every file.

    Instead of the old behavior, now in the new version it basically seemed to freeze for about 2 seconds (in Visual Studio, not Unity) and then that was it. No popup, no visible unloading or reloading of anything. It just... worked.

    There wasn't a limbo period where unity was frozen waiting for visual studio's prompt to be dealt with, either.

    I really didn't like the feel of VS 2017, because of how it does the underlined links and a bunch of other stuff. However, if you just export all your settings from VS 2015 and then reimport those into VS 2017, you'll have essentially the same feel as before. Just remember to turn the Text Editor toolbar back on, and then do whatever you did before with your docking and pinning of sidebars and bottom bars.

    Well -- this is certainly a game-changer!
     
    guavaman likes this.
  12. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    That shouldn't be the case unless I'm not understanding something correctly. All of Rewired's classes that you usually work with are in the main Rewired_Core.dll which should be accessible from any .asmdef. (Edit: Verified this does work.) There's no way to put Rewired_Core.dll into an .asmdef because it's already compiled. Any other files included with Rewired as C# scripts are just either helpers so Rewired's DLL can get information from the Unity assembly, examples, or addons like integrations, Control Mapper, Touch Controls, etc. If you were to need to access something directly from one of the addons in a script, then yes, this would be a problem and those scripts would have to be added to an asmdef.

    Yeah, that looks like how it's going to have to be -- a totally manual process by the user. I'll probably add some documentation with some guidelines on how to do it along with caveats (addons with dependencies).
     
    Last edited: Nov 30, 2017
    x4000 likes this.
  13. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    10-4. Regarding things I need to touch, typically it's just the RewiredConsts (which I happen to put in the Rewired folder but can put elsewhere), the ControlMapper stuff (which it sounds like can be moved), and then the core Rewired bits from your dll.

    On that note... if I'm not using things like the dependency installer and whatnot at the present time, are there some folders I can delete in order to save on assembly-reload time in the editor? I've noticed that the things that are looking for that Rewired_Core.dll are things which run pretty frequently (after every compile and every play of the editor), and being able to scrape that code out of my project since things are already installed and set up would save me some time, I imagine. Earlier in the thread it was recommended by the unity guy to basically do that sort of thing in order to get that "post compile freeze" time down.
     
    guavaman likes this.
  14. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Then, yes, the Control Mapper files would need to be put into an .asmdef. They can be moved, but when you upgrade Rewired, it won't be able to upgrade Control Mapper as well and you'll have to do that manually from Rewired/Internal/Assets/Extras/ControlMapper.zip.

    No. The amount of code running every time you compile and stop Play mode in the editor is extremely minimal. All it does is check if Rewired has been installed. If not, it runs the installer. If so, it checks whether the Rewired Unity Input Manager entries exist. It's a very fast process. This is in Rewired_Editor.dll and cannot be removed.

    As I mentioned before, the only thing affecting your compile time is the serialized controller data. It is explained here. There is no solution but to remove controller definitions that you don't care about.
     
    x4000 likes this.
  15. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Indeed. It would be nice to have it all included and automatically just work, but I can't see a way to do this.

    That would be fine actually since Rewired isn't aware of the classes anyway being in a DLL. The classes reference Rewired but not vice versa.

    Rewired being mostly contained in a DLL, there are actually a lot fewer problems than for an asset distributed as scripts. Those would face even bigger challenges trying to include .asmdefs with the asset.

    I didn't realize that. That doesn't make a whole lot of sense to me. Why would Assembly-CSharp.dll need to be recompiled when changing something in a custom assembly? Perhaps because Assembly-CSharp.dll has a reference to all custom assemblies? But I wouldn't think it would need to be recompiled until something in that assembly actually changed.

    Yeah, too many caveats because you can't know what the other asset will do or what the user may manually do with it.

    Another alternative is reflection, but I really hate using it for many reasons.

    Yes, but this doesn't work in Unity 5.0 - 5.2.9 which some people still use (it will extract by path and duplicate files that have been moved). However, that's not the biggest problem for me. With Rewired, it does automatic management of addon packs distributed as zip files. It installs them for you (or you do it from a menu) and it upgrades them automatically when Rewired gets upgraded by extracting the contents of the new zip over the old. Once you move those files, 1) Rewired doesn't know they've been installed 2) Wouldn't have any way of extracting the new version over the old. I would have to redo the whole system using Unitypackages instead. This is just a problem with the design of my system. Most assets would be upgradable by the method you describe.
     
    Last edited: Nov 30, 2017
    x4000 likes this.
  16. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    10-4, that all makes good sense.

    This is one of the reasons I originally got in touch with you, and why I've been moving assets into asmdef folders. It wasn't just for the heck of it, heh.

    The reason for the behavior is the dependency tree -- whenever any assembly is compiled, then everything that depends on IT is compiled as well. Assembly-CSharp depends on everything, so it always gets compiled no matter what else is compiled. In my case, with my current title prototype I'm managing not to even have an Assembly-Csharp file.

    This is mentioned in the dependency tree documentation here, although it could stand to be a lot clearer: https://docs.unity3d.com/2017.3/Documentation/Manual/ScriptCompilationAssemblyDefinitionFiles.html

    It's buried way down in there:

    "It is highly recommended that you use assembly definition files for all the scripts in the Project, or not at all. Otherwise, the scripts that are not using assembly definition files always recompile every time an assembly definition file recompiles. This reduces the benefit of using assembly definition files."

    Hence my crusade to do as they said. ;)
     
    guavaman likes this.
  17. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    It makes sense, but that isn't how it works in VS which is why it was confusing me. Recompiling a dependency doesn't automatically trigger a recompile of referencing assemblies. It does recompile dependencies if something has been changed and the assembly that references them is being recompiled. But not recompiling the referencing assembly could leave it in a state where something important changed in the dependency causing the referring assembly to not even compile. That's why they did it -- to make sure the whole project always compiles. It's essentially like building the solution each time anything changes. Got it.

    :confused:

    My first inclination of thinking this change was rather major and was going to require a rethink of the structure of the asset and probably a separate branch to support it properly was actually correct after all. This can't easily be jury-rigged into existing systems and requires things to be designed to fit the workflow. I always want things to automatically just work out of the box for the user, but that is far easier said than done in this case.
     
    x4000 likes this.
  18. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    Fortunately it's not so bad as being the equivalent of rebuilding the whole solution.

    In this case, they're only detecting things that were directly changed, and then walking up the dependency tree from there. So if I change things in one asmdef file folder but no others, and nothing depends on it, then it just compiles that one folder's stuff. That's what is so amazing here.

    But if I have two dependencies on that folder (assembly), then those two also get recompiled "just to be sure." 99% of the time it accomplishes nothing, but 1% of the time something in those depends on something that I changed, and it gives me a compile-time error rather than a runtime one.

    Frankly it would be nice to have it NOT do that, but then have the equivalent of "rebuild all" on the unity side, since it would avoid this whole mess while still giving the benefits of asmdef files. In that case it would remove the "it's best to use them for everything or not at all" caveat.
     
    guavaman likes this.
  19. guavaman

    guavaman

    Joined:
    Nov 20, 2009
    Posts:
    3,886
    Not re-build, just build (only the changes and referencing assemblies).

    It's definitely a major change and a very powerful feature. I expect every asset released post-2017.3 will want to use them in some way where possible.

    If they added support "partial" asmdefs, it would actually solve most of the problems with Rewired. I could add .asmdefs to the main Rewired package only in the folders that need them (examples, internal/scripts), then add them also in each addon (Control Mapper, etc.), have all of those compile to the same Rewired_CSharp.dll, and then for the addons that have external dependencies (UFPS integration, etc.), I could just leave out the .asmdef and those scripts would compile in Assembly-CSharp.dll. Everything could be included in one assembly even when users add addons and there would be no issue with external dependencies. Anything in a custom assembly that needs to reference one of the addons (Control Mapper) would just add a reference to Rewired_CSharp.dll.

    Of course, if the user decides to put UFPS in an .asmdef, they'd have to do the same for the UFPS integration in Rewired, but that's expected. However, if UFPS then released an update that included everything in an .asmdef, then I would have to change Rewired's integration to also use an .asmdef and include a reference to the UFPS assembly which would work okay since it just uses the assembly name string. This is probably how we will manage asset dependencies in the future when everything includes .asmdefs. Thinking out loud here...
     
    x4000 likes this.
  20. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    Ah, right -- rebuild, not build. I'm a Ctrl+Shift+B guy, myself. ;)

    And in terms of your other thoughts, I agree. I think the unity folks in this thread might not be the happiest about that -- and for goodness sake I hope they don't delay asmdefs past 2017.3 because of this or something -- but I think that this does show a good use-case for how things should probably evolve.

    UFPS and Rewired and Behavior Designer and so on are all over the place. RTP plugs in with a bunch of things, and so does Gaia and so on. All of those dependencies are going to need to be handled in some fashion. Heck, even things like Hx Volumetric Lighting and Alloy have integrations, although that's just with shader keywords, kinda-thankfully (I'm not the biggest fan of shader keyword spam, given the limits on how many there are, but this one was worth it).
     
    guavaman likes this.
  21. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    15.5 will be a game changer indeed. Apart from the no-Prompt Reload, it will feature Live Share. Basically you can share your development context with others, either for coding or debugging. Here's a link.
     
    x4000 likes this.
  22. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    Nice, that's pretty slick!

    Interestingly, if unity gets a project added or removed, then it still has the prompt about the solution reload, although it looks different by a small bit. It then reloads everything again after that prompt, and actually takes a little longer than before from what I can tell. But most of the time that doesn't happen... kinda.

    Whenever you install a new asset from the asset store, it usually comes with SOME code, so it winds up creating the Assembly-CSharp project for a moment. I can see VS 2017 updating in the background while it does this. I don't switch to it, though. Then I either create and asmdef file in the new folder, or more likely I move (and split) the asset into two existing asmdef-based folders.

    At that point the Assembly-CSharp project dies again, and even though I never went to VS 2017 it now wants me to reload the solution because of what it was doing behind the scenes. Sometimes it even wants me to reload the solution TWICE in a row, which is new.

    So it's a game-changer for daily use where we're not really adding assets constantly. But during a prototyping period where you're adding and removing stuff a lot, it does create at least as much hassle as before. Bummer, but hopefully something they fix.
     
    SugoiDev likes this.
  23. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,487
    At a higher level I think folder abstractions are fine. Implementation being anything other then file based doesn't make sense to me.

    The resources folder ran into the limitations of this approach. They should have used an asset bundle approach to start with, but didn't, and now are in a situation where it's nearly impossible to deprecate Resources because it's so engrained. Well that and they kind of dropped the ball by not coming up with a higher level folder abstraction for asset bundles.

    At a high level I think some in unity realize special folders were not the best design. Fine that happens as you evolve. But if you want to fix it you have to make sure to not keep adding to a bad design. The current way definition files work does that.

    In the end they are going to realize that even without the above points, it just doesn't work if you try to do it via folders. Not in a way that results in something people will actually use.

    What I would do is start with a file based UI and api to go along with it. Plus a folder level abstraction option. And then give it some time to uncover common use cases, and gradually add in some higher level abstractions that cover those as they are discovered.

    I think an api in this case would actually get the most use. Most projects large enough to benefit from this have developers. Like give me an api that takes a path and gives me back a dictionary with keys being a category and value being a list of source files. Categories being thing like editor files, non editor files, etc.. Scripts that use that for common use cases would get out on the forums in short order.

    Also, the correct scope for this is the entire project, not individual assets from the asset store. If I see definition files in assets I will cry.

    I think with a relatively simple api with fine granularity like I outline above, it's then a trivial script that can do exactly what you want for your project. A script that just has two lists of paths, one include and one exclude, would I think cover most common use cases. And if not would be simple to modify to specific needs.
     
    x4000 likes this.
  24. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,487
    One more point. The people this helps the most, are most likely talented enough to actually do this right once it's a major issue. I know that would be my approach. It's actually very simple I'm surprised there isn't an asset on the asset store that does this already.
     
    x4000 likes this.
  25. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,487
    The biggest pain point I've always had is having to wait for everything to to reload when making code changes. Unity does a lot more then just recompile assemblies when you update code. I can guess at what that might be, but it's really easy to see if you just look at how long it takes mono or VS to compile an equivalent amount of code. It's not even close.
     
    x4000 likes this.
  26. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    For many years we didn't even use the unity editor, but just compiled from VS and then had that replace the dll in the compiled project folder for testing, partly for this reason. We loaded everything off disk rather than through the unity interface, etc. But that's no good for 3D, which I've only moved into in the last two years; the half-decade or so before that was all 2D.

    Even now, working in 3D, on AI War 2 we are mostly working with external dlls of our own. We have very few scripts in the main project, and then compile the dlls and it loads them, and yes that's slow. We introduced a modding interface that allows for custom dll loading, and that's actually wicked fast by comparison, even in the editor. Basically we use Assembly.Load() from the filesystem.

    The bad thing about that approach is that then nothing in the editor can use those monobehaviours directly. So either we're constructing things at load-time and then cloning from there as needed, or in some other cases having abstract base classes in core dlls that the editor does have access to, and then the implementations for those are in external code. The location of the implementation then has to be in an xml file that gets read and which points to the correct dll and class.

    The amount of indirection that leads to is a real pain in the rear, but it's the fastest sort of thing I've seen thus far for pure compilation. For stuff that I'm working on more solo, rather than with the rest of my team, I'm not taking that approach.
     
  27. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    282
    As @x4000 mentioned, it's probably because of that (non-custom assemblies can see all custom assemblies).
    One common gotcha of not recompiling it all down the depdency tree, is the way constant strings are handled: if you have a const string in a custom assembly that is referenced by another assembly, if you change it in the custom assembly without recompiling the other assembly, the other assembly would still have the old value instead of the new. This is because .NET bakes certain constants directly into the assembly.

    So, the safer path is to recompile everything that doesn't have a strict dependency tree (that is only possible with magic folders and the asmdef files).

    I feel you, for many reasons.

    Fair point. Cross platform, cross architecture and cross Unity versions is no joke, for sure.

    I'm doing the same. I love seeing only my own named assemblies in my project view.

    I'm actually considering getting a subscription to Jetbrains Rider just because of solution reloads in Visual Studio.
    In Rider they happen seamlessly, with very little delay.

    Hell, I even created an external helper that intercepts the modifications Unity would do to the projects and, instead of changing the files, uses the Visual Studio API to actually request the changes, one by one, to be handled by Visual Studio itself. This completely removes the reloading and makes adding/removing/moving/etc files around be super fast. I never got it to quite the polish I wanted, so it was never released. Using the Visual Studio API externally and dealing with all of its retrying and thread apartments was very intense.
     
    x4000 likes this.
  28. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    One of the other things that we have done in the past is made projects and solutions that were our own, that unity wouldn't touch. They would then just have a *.cs include set manually inside their file list, rather than having a full list of the files inside it.

    Unfortunately it doesn't detect freshly-added files that way, but you can do a quick project unload, reload in VS if you have to. Other than that if you're adding your C# files from within VS rather than from within unity, it never becomes an issue. Aside from when someone else adds something via svn, anyway.

    But that's a trick we've used in order to get around unity messing with our VS solutions and projects -- then those are OUR solution and projects, and unity is blind to them. But since it's just a different project including all the same C# files from the unity folder, unity sees those just fine.

    I think if it becomes too much of a hassle with solution reloading, I might just take that approach again rather than trying to learn a new IDE like Rider. I've used a variety of IDEs over the year, and I believe I used to use a decompiler or obfuscator or somesuch from JetBrains, 10+ years ago. But I've been using VS since it C# 1.0 came out in 2002 or around then, and I suddenly feel like a very old and stodgy man when it comes to being stuck in my ways. ;) Other IDEs just don't feel... natural, I dunno.
     
  29. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    282
    I was in a very similar situation, but not with that many years.
    I had some previous experience with other Jetbrains IDEs, like PyCharm, IDEA and RubyMine, so maybe my transition won't be as painful. One key point for me is that Rider is based on ReSharper, and I always had VS with ReSharper (since everywhere I worked was always dependent on it). Only recently I've been using VS without it because I'm on cup noodles budget and subscriptions kill me.

    From my testings with the EAP and trials, as well as seeing that they have at least one or two devs just to do Unity integration, I think Rider will have a very good adoption in the Unity world. If they ever release a "Community" equivalent version, they would probably become standard with new devs. I think that's healthy as it will force Microsoft to dedicate some more love to make VS even better with Unity.


    I'm not a huge fan of having separate DLLs that I maintain myself, particularly during prototype/exploration phases.
    In the past I went kind of crazy about that (because I wanted that sweet, sweet test coverage) and I got a bit of a trauma from it.
    I'm hoping the custom assemblies are here to stay because I think they have a very nice balance.
     
    x4000 likes this.
  30. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    That's the beauty of the approach I was describing above: you're not making custom dlls of your own. You can compile your dlls all you like, but just send them to temp or whatever. It's just for compilation-readiness checking.

    The method is that you basically just take a copy of the unity solution and projects, and then change the includes to be *.cs rather than any specific files. At that point unity doesn't know where that solution and those projects are, so it can't touch them. It will make its own solution and projects... but ONLY if you try to open the code from within unity.

    You'll lose the ability to double-click a script in unity and have it take you to the right file, because that would open the unity version of the solution and project and be very slow. But other than that, all of the other functionality remains the same. Aside from if any files get added via a process other than your own addition of files through VS, you'd need to unload and reload your affected project(s) in VS, or simply restart VS.
     
    SugoiDev likes this.
  31. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    282
    Ah, got it!


    Yeah, when I was creating that external tool I mentioned (to modify the sln/csproj using the VS API) I ran into that issue. I ended up creating a processor that intercepts when Unity is about to open something and handles that for me. That way I can always open my own solution or projects instead of letting Unity open the file its own way.

    In case it interest anyone, the approach is to just a method like this

    Code (CSharp):
    1.  
    2. [UnityEditor.Callbacks.OnOpenAssetAttribute(0)]
    3. private static bool OnOpenedAsset(int instanceID, int line) {
    4.     var ext = Path.GetExtension(assetPath).ToLower();
    5.     var name = Path.GetFileNameWithoutExtension(assetPath).ToLower();
    6. }
    7.  
    Then you can decide how to open the file by switching over the extension.
    If you return true from that method, Unity will assume you handled the asset opening and will do nothing more.

    I also tapped into the solution generation and made it stop. I rolled back from that approach because of madness, but still use the asset opening processor, since it is particularly important for my scene opening (I have some "compound scenes" that I want opened in a special way, even when the user double clicks the scene in the project view).
     
    Lichter and x4000 like this.
  32. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    Wow, that's a really slick code snippet! It's a shame to have it buried in here. Someone will be wanting something like that for either this or some other purpose, and maybe they'll get lucky on a google search. That old unity community wiki is defunct now, isn't it? Is there anywhere to post stuff like that now?
     
  33. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    282
    I think the wiki is still around, but I'm not sure if it's still taking contributions.

    That's something I would like to know, too! Maybe there's some cool github repo somewhere?
     
  34. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    1,733
    You could ask a question in here and reply with the answer yourself to make the information more accessible for others.
     
    hippocoder and x4000 like this.
  35. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    Heh -- good point!
     
  36. Infrid

    Infrid

    Joined:
    Jan 14, 2012
    Posts:
    67
    Script assembly 'ThirdPartyFXScripts.dll' has not been compiled. Folder containing assembly definition file 'Assets/3rdParty/FX/ThirdPartyFXScripts.asmdef' contains script files for different script languages. Folder must only contain script files for one script language.

    This is driving me crazy. I was hoping to just add an assembly def asset to all my 3rdparty tools/editor scripts etc; but I have to do each asset one by one as I get this error frequently, and it gives ZERO indication what the problem is. I have no js files/ boo files, any of that silliness. Will it report this error for shaders? if so WHY???

    Making assembly def files a total pig to use right now - How do I work around this. Instead of 4 assembly assets, my project currently has 15 and counting. Not usable at all.
     
  37. Infrid

    Infrid

    Joined:
    Jan 14, 2012
    Posts:
    67
    Would also be great to be able to tell the assembly definition to exclude certain folders, and also have it check that a dependency isn't already added when selecting from the list.
     
  38. Infrid

    Infrid

    Joined:
    Jan 14, 2012
    Posts:
    67
    I've backed out using the system for now. I hope you guys can work it out; but I fail to see how anyone in a real scenario beyond your blog post, who uses asset store assets (i.e. every single unity developer in the world) can feasibly use this. Hope to be wrong.
     
  39. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    I haven't run into those issues, but it took a bit of a while to get things going. It may be related to the bug with the editor flag, I'm not sure. Targeting PC, the only time I saw that error was because of an asset store asset using some js files. At the moment I have a prototype project with about 40 asset store assets in it with just 12 asmdef files in it (4 of which are exclusively for my own code). Shaders definitely don't impact asmdef folders.
     
    elbows and SugoiDev like this.
  40. pkbis

    pkbis

    Joined:
    Aug 1, 2017
    Posts:
    18
    You are mentioning this needs to have latest version of VSTU, which is available only for VS 2015 and 2017. What happens if you try to open the project with assembly definition files in older VS (VS 2013)? Will it just put everything into the "old" assemblies, but the project itself will be perfectly OK and the assembly definition files will work as intended for compilation?
     
  41. npatch

    npatch

    Joined:
    Jun 26, 2015
    Posts:
    143
    Whatever it is, it won't be good I guess.
     
  42. Infrid

    Infrid

    Joined:
    Jan 14, 2012
    Posts:
    67
    Thanks for the response. I can't find a damned js file anywhere in the project. Was so dissappointed I couldn't just drop one assembly def file in my 3rd party assets folder, and one in my scripts folder. Would've been magical.
     
  43. codestage

    codestage

    Joined:
    Jul 27, 2012
    Posts:
    1,287
    Hey, @lukaszunity

    Just wish to let you know looks like assembly definitions are not get into the consideration when making reimport all for the project while having running and configured Cache Server.
    I've submitted a bug report with more details: 975773
     
  44. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,941
    Got conflicting information. Do we rely on asmdefs from 2017.3 onward or are there major changes afoot?
     
  45. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,134
    how do I do that?
     
  46. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    You have to install VS 2017 Beta 15.5 or higher. When you do, make sure to install VSTU when you go, but not Unity itself.
     
  47. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    2,134
    ok thanks, too many steps already, I'll just wait for the fixed version in 2017.3
     
  48. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    I think mainly it's a matter of waiting for the non-beta new version of Visual Studio 2017.
     
  49. rastlin

    rastlin

    Joined:
    Jun 5, 2017
    Posts:
    114
    VS 2017 version 15.5 has been released 2 days ago.
     
    x4000 likes this.
  50. x4000

    x4000

    Joined:
    Mar 17, 2010
    Posts:
    308
    I'm behind the times! That's good news.