Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Assembly Definition Woes

Discussion in 'Editor & General Support' started by Wahooney, Dec 20, 2017.

  1. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    I'm sorry, you feel that way but what you are describing would negate the other settings in an asmdef(per platform, defines constraints, Test & Editor only assemblies). Compiling with asmdefs and without can give different results.

    We understand the issues users are having and are working on improvements. We are adding support for out of branch files, what some have referred to as partial asmdefs. With this, you will be able to continue with the Editor folder approach and simply use an assembly reference(asmref) in each Editor folder which would all compile to a single asmdef(or more).
    You will then be able to continue using assets that have Editor folders and assets that use asmdefs together.

    I should mention I'm not actually part of the scripting team but I will be the one doing the work on this so that it can be done quickly because I know it's bothering you guys.
     
  2. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    269
    >We are adding support for out of branch files, what some have referred to as partial asmdefs.

    Oh man, am I glad to read that. This is the thing that will allow us to trivially use asmdef files without having to modify asset store packages.
     
    Flavelius and karl_jones like this.
  3. JayArgh

    JayArgh

    Joined:
    Jul 23, 2013
    Posts:
    8
    @karl_jones I appreciate your pitching in on this thread. Thanks for the info.

    I'm working on a very large project, a container that includes 20+ licensed games and which recently failed to compile due to, it appears, an undocumented code limit for Assembly-CSharp.dll. I'm working on updating the project from 5.6.5f1 to 2018 now, using asmdefs to split up the code and avoid bumping against the limit, but I'm finding that adding separate asmdef files to every Editor folder for every game is a painful process - besides being tedious (one game alone has 38 Editor folders), there are interdependencies between some of those editor scripts that mean I'm having to track down, say, Assembly-{gamename}_Editor-34 and make sure it's listed as a reference for Assembly-{gamename}-Editor-20, etc. The alternative - moving all Editor scripts into a single folder for each game - is a possibility but will make it harder to maintain such scripts if their corresponding plugins are updated or removed.

    Will the "out of branch files" feature easily let me compile all these files into a shared assembly, the way Editor folders would if I wasn't using asmdefs at all? If so, that's a helpful step. For my own use-case, it might be easier if there was just an override option to exclude subfolders named Editor from their parent asmdefs, letting those scripts instead get automatically compiled into Assembly-CSharp-Editor.dll with an automatic dependency on everything previously compiled, as Assembly-CSharp does for any files unassociated with an asmdef file.

    - JR

    PS: FWIW, I found this thread by googling "unity 2018 partial assembly definition", so "partial asmdefs" did seem an intuitive term to me; I'm not sure what's meant by "out of branch files".
     
    SugoiDev likes this.
  4. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    269
    Yeah, we've been calling it partial asmdef ever since custom assemblies were out. I don't even remember who started calling it that, but it is the most intuitive name we've got.

    Maybe "out of branch files" will make sense once it's out, but right now it's not intuitive at all.
     
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    The Assembly Definition Reference (asmref) requires there to be a matching asmdef. They have no settings inside of them, just a reference to the asmdef.
    The reason we decided not to support actual partial asmdefs, i.e having multiple asmdefs with the same name is that they could have conflicting settings which would make things confusing, especially since the settings would need to be applied to all the source files, not just the ones in that particular partial asmdef.
    So you would need a master asmdef but it can be anywhere, it does not even need to have any source files with it.
    So if you had lots of editor folders then you could place these asmrefs in all the folders and tell them to reference a master asmdef which could be somewhere else. So you do still need an asmdef, they do not work without.
    We dont support excluding files, maybe we could allow an asmref to reference Assembly-CSharp as an alternative to this?

    We are also considering per platform settings for asmrefs. E.G only include these source files if compiling for Android. You could do all sorts of things with partial classes or class variants then. Thats still just an idea though, not planned just yet.
     
  6. yatagarasu

    yatagarasu

    Joined:
    Apr 24, 2013
    Posts:
    27
    That would be good. Now having 15 asmdefs in the project, and Visual Studio sucks on every project reload, open file from editor or connecting a debugger. Thinking about moving back to precompiled assemblies, because all the system makes no sence when it slows down the development process.

    Another useful feature would be ability to add preprocessor defines for asmdefs.
     
  7. ifisch

    ifisch

    Joined:
    Jul 15, 2012
    Posts:
    28
    That's the exact same suggestion you made before and it still involves us putting dozens of asmdefs in each of our editor folders. That's no good.

    I don't understand how compiling without asmdefs, only at build time, would "give you different results" that could cause any sort of negative issue. Wouldn't it simply package everything into the main c# assembly (like it would if you had never setup the asmdefs)? Why would that be a problem?
     
  8. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    As I said, they could have conflicting settings which would make things confusing, especially since the settings would need to be applied to all the source files, not just the ones in that particular partial asmdef.

    Assembly Definition settings such as platform, define constraints, test assemblies would all be ignored and they would just be combined into a single assembly. Creating a very different build.

     
  9. JayArgh

    JayArgh

    Joined:
    Jul 23, 2013
    Posts:
    8
    FWIW, the solution we've ended up going with is this:
    Create a top-level Editor folder per game (I actually called it "_Editor" to distinguish).
    Create folders within _Editor to duplicate the paths to any Editor folders. So, for instance, a folder called Assets/{GAME}/Editor would move to Assets/{GAME}/_Editor/Editor. A folder called Assets/{GAME}/Scripts/LeanTween/Editor would move to Assets/{GAME}/_Editor/Scripts/LeanTween/Editor.
    Create a single asmdef in the {GAME} folder.
    Create a single Editor asmdef in the {GAME}/_Editor folder. Set the other asmdef as a reference/dependency.

    It's an annoying process, but significantly less time-consuming than creating separate asmdefs and managing the references between them, and the tree structure is generally preserved so that we're still able to see where things came from, just with one more step each time. Suboptimal, yes, but thus far it seems the most workable solution.
     
  10. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    That sounds an awful lot like my suggestion
    :p
    Sounds like a good approach.
     
  11. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    269
    That's what we've been doing ever since custom assemblies landed.

    The biggest issue we have is having the repeat your directory structure in two places. It creates a lot of redundancy when you have lots os directories and is especially bad with asset store stuff, since you will have to keep track of your changes and propagate them every time the developer changes the structure.

    Another annoying issue is not having the related files close together in the IDE. You have to navigate a lot more to find your files.



    Related files are far away. It's easy to rename the folder to something else and forget that its counter even exists.
    This is the current solution.

    Code (CSharp):
    1. Assets/Game/Editor/Characters/NPCs/Ghosts/CommonGhost/Eyes/EyeEditor.cs
    2. Assets/Game/Characters/NPCs/Ghosts/CommonGhost/Eyes/Eye.cs

    Files are very close. It's much rarer to rename something and forget to propagate the change. Easy to navigate in the IDE, and also easy to see that the Eye component actually has an editor.
    This would only work with partial asmdef files.

    Code (CSharp):
    1.  
    2. Assets/Game/Characters/NPCs/Ghosts/CommonGhost/Eyes/
    3. ---------------------------------------------------Eye.cs
    4. ---------------------------------------------------Editor/EyeEditor.cs
     
    Hunter_Bobeck likes this.
  12. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    We are working on a solution so you can keep them all together in the future but still have them into one assembly. See the asmref stuff I mentioned earlier in the thread.
     
    Hunter_Bobeck likes this.
  13. SugoiDev

    SugoiDev

    Joined:
    Mar 27, 2013
    Posts:
    269
    That's gonna be awesome!
     
  14. JayArgh

    JayArgh

    Joined:
    Jul 23, 2013
    Posts:
    8
    It IS an awful lot like your suggestion! We added the twist of duplicating the path to each Editor folder so we can still see where they came from. Perhaps your proposed automatic utility would do the same? :)

    But as I said, and for the reasons mentioned by others: it's not preferable. Automating that process would save a few minutes per project (once I had a rhythm going), but I would have preferred for all Editor folders under a common asmdef to automatically combine into an Editor-only assembly that depends on that parent asmdef, thereby gaining the benefits of splitting up assemblies without losing the convenience of the Editor folder naming convention.
     
  15. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    That was how it was going to work. I then changed it so it would automatically place an asmdef in every folder but it's tricky getting all the references correct and often ends up with cyclic references so the asmref is needed really.
    Once thats in ill change the tool so it places an asmref in every Editor folder.
    Doing the automated Editor folder thing for an asmdef would create similar problems with the references, it's hard to get them right automatically and referencing everything often causes the cyclic issues. The asmref solution will allow you to configure an Editor asmdef with the correct references and then just add additional source code directories via the asmrefs.
     
    Hunter_Bobeck and SugoiDev like this.
  16. Colin_MacLeod

    Colin_MacLeod

    Joined:
    Feb 11, 2014
    Posts:
    92
    I wanted assembly definition files for all third-party assets, with separate files for each Editor folder underneath.

    So I took @LVermeulen's very cool script and adapted it a bit.

    This version doesn't delete assembly definition files - it just creates them. But it won't overwrite a file that already exists. That means you can run it each time you add a third-party asset, and it should just create new files for the asset but leave the rest alone.

    I found I needed to tweak some of the dependencies a bit and, after that, it worked for me.

    There's a list of directories you don't want to generate for - basically your project directory and Resources go in here. And I wanted a separate assembly definition for each directory in Plugins.

    Hoping this might be useful to someone else...

    Code (CSharp):
    1.  
    2. using System.Collections.Generic;
    3. using System.IO;
    4. using System.Linq;
    5. using UnityEditor;
    6. using UnityEngine;
    7.  
    8.  
    9. #pragma warning disable 649 // CS0649 - always have its default value
    10. // ReSharper disable once ClassNeverInstantiated.Global
    11. internal class AssemblyDefinitionType
    12. {
    13.     public string name;
    14.     public List<string> references;
    15.     public List<string> includePlatforms;
    16.     public List<string> excludePlatforms;
    17. }
    18. #pragma warning restore 649 // CS0649 - always have its default value
    19.  
    20. // Based on https://forum.unity.com/threads/assembly-definition-woes.509541/#post-3451964
    21. public static class AssemblyDefinitionGenerator
    22. {
    23.     // ignore everything in these directories altogether - include anything here you want to setup manually
    24.     private static readonly string[] IgnoreDirectories = new string[]
    25.     {
    26.         "_Project",
    27.         "Resources"
    28.     };
    29.     // don't create parent assemblies for these directories - create them one level lower
    30.     private static readonly string[] NoAssemblyDirectories = new string[]
    31.     {
    32.         "Plugins"
    33.     };
    34.    
    35.     [MenuItem("Tools/Create Assembly Definition Files")]
    36.     public static void TurnOnAssembly()
    37.     {
    38.         CreateAssemblyDefinitions(new DirectoryInfo(Application.dataPath), null, false, "");
    39.         AssetDatabase.Refresh();
    40.     }
    41.  
    42.     private static List<string> _editorAssemblySiblings;
    43.     private static int _duplicateNumber = 0;
    44.  
    45.     private static void CreateAssemblyDefinitions(DirectoryInfo directory, FileInfo parentAssembly,
    46.         bool requireAssembly, string assemblyPrefix)
    47.     {
    48.         if (IgnoreDirectories.Contains(directory.Name) || !ContainsSources(directory)) return;
    49.  
    50.         var files = directory.GetFiles("*.asmdef");
    51.         foreach (var file in files)
    52.         {
    53.             parentAssembly = file;
    54.             _editorAssemblySiblings = new List<string>();
    55.             _duplicateNumber = 1;
    56.         }
    57.         // if there is no parent assembly file, it's not the root, and it contains source code, create an assembly
    58.         if (requireAssembly && parentAssembly == null &&
    59.             !NoAssemblyDirectories.Contains(directory.Name))
    60.         {
    61.             var assembly = new AssemblyDefinitionType {name = assemblyPrefix + directory.Name};
    62.             var filename = assembly.name + ".asmdef";
    63.             var pathname = Path.Combine(directory.FullName, filename);
    64.             UnityEngine.Debug.Log("Writing parent " + pathname);
    65.             File.WriteAllText(pathname, JsonUtility.ToJson(assembly));
    66.             parentAssembly = directory.GetFiles(filename)[0];
    67.             _editorAssemblySiblings = new List<string>();
    68.             _duplicateNumber = 1;
    69.         }
    70.                    
    71.         var directories = directory.GetDirectories();
    72.         foreach (var subdirectory in directories)
    73.         {
    74.             if (subdirectory.Name != "Editor")
    75.             {
    76.                 // add a prefix to plugins
    77.                 var prefix = NoAssemblyDirectories.Contains(directory.Name) ? directory.Name + "-" : "";
    78.                 CreateAssemblyDefinitions(subdirectory, parentAssembly, true, prefix);
    79.                 continue;
    80.             }
    81.  
    82.             if (!ContainsSources(subdirectory)) continue;
    83.  
    84.             // create a assembly file based on the Parent one, only with includePlatforms changed to Editor
    85.             // assembly name is the parent assembly name + directory that contains the editor folder + "Editor"
    86.             var editorAssembly = JsonUtility.FromJson<AssemblyDefinitionType>(File.ReadAllText(parentAssembly.FullName));                    
    87.             editorAssembly.references.Add(editorAssembly.name); // add parent assembly as a reference
    88.  
    89.             // make the name unique
    90.             var editorAssemblyName = editorAssembly.name;
    91.             if (!editorAssemblyName.EndsWith(directory.Name)) editorAssemblyName += directory.Name;
    92.             editorAssemblyName += "Editor";                
    93.             if (_editorAssemblySiblings.Contains(editorAssemblyName))
    94.             {
    95.                 editorAssemblyName += _duplicateNumber;
    96.                 _duplicateNumber += 1;
    97.             }
    98.             _editorAssemblySiblings.Add(editorAssemblyName);
    99.            
    100.             // only create an assembly if we don't have one already
    101.             var pathname = Path.Combine(subdirectory.FullName, editorAssemblyName + ".asmdef");
    102.             var file = new FileInfo(pathname);
    103.             if (file.Exists) continue;
    104.  
    105.             editorAssembly.name = editorAssemblyName;
    106.             editorAssembly.references.AddRange(_editorAssemblySiblings); // for subeditor folders to reference the above editor assemblies
    107.             editorAssembly.includePlatforms = new List<string> {"Editor"};
    108.             UnityEngine.Debug.Log("Writing " + pathname);
    109.             File.WriteAllText(pathname, JsonUtility.ToJson(editorAssembly));
    110.         }
    111.     }
    112.  
    113.     private static bool ContainsSources(DirectoryInfo directory)
    114.     {
    115.         var sourceFiles = directory.GetFiles("*.cs", SearchOption.AllDirectories);
    116.         return sourceFiles.Length > 0;
    117.     }
    118. }
    119.  
    Original script is here: https://forum.unity.com/threads/assembly-definition-woes.509541/#post-3451964
     
    Ash-Blue and MikeMarcin like this.
  17. Wriggler

    Wriggler

    Joined:
    Jun 7, 2013
    Posts:
    83
    Just ran into this issue with Assembly Definitions too. Everything looked good in the Editor, but when I went to build our bundles on our build server I discovered that the Editor special folder naming convention is ignored. Yikes.

    My two choices right now are to either:
    1) Spend a while manually setting up asmdef files in all the third party assets we use (yuck), manually managing their dependencies (double yuck), as well as inheriting the responsibility for merging all future third party updates, potentially forcing me to rework their codebases for future versions.
    2) Don't use Assembly Definitions.

    It's not even a choice - I just deleted all the asmdef files and am going old school. Option 1 adds way too much overhead to our team; I don't want the responsibility of managing all the Asset Store code in our project... that's why we purchased the assets in the first place. Any large scale project will run into this issue.

    @karl_jones: I do understand the stance you're taking in this thread, but it's rather idealistic. Right now using asmdefs adds so much overhead for any non-trivial project that it might as well not exist as an option. Perhaps we'll review this again when every asset in the Asset Store is using the package manager (in a million years, probably), but until then this feature isn't realistically usable, in my opinion.

    Ben
     
    Hunter_Bobeck and Harinezumi like this.
  18. Alexees

    Alexees

    Joined:
    Nov 8, 2017
    Posts:
    217
    @Wriggler I agree with your statement, but as it is with all new inventions, it takes time to adapt. Most cars still run on gas even though we have battery powered ones for at least a decade now.
    In my opinion:
    - Don't convert a project you started just yet. It's simply too early due to all the assets in the asset store not matching the criteria. And reworking your carefully created folder structures and namespaces is just a pain in the butt.
    - Consider it when starting a new project, including contacting to asset vendors providing ASMDEF ready solutions. I tried that once and they were pretty fast in providing a package making use of them
     
  19. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    653
    Meanwhile, are there any news regarding this issue?
     
  20. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    Which issue are you referring to? There's quite a few in this thread.
     
  21. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    653
    Having multiple Editor folders and being able to merge them into one Editor-assembly
     
    Harinezumi and fherbst like this.
  22. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    653
    Or did i miss that some change already went live?
     
  23. Flavelius

    Flavelius

    Joined:
    Jul 8, 2012
    Posts:
    653
    Are there any plans?
     
  24. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    274
    After reading the manual on assembly definitions I misunderstood the part about plugins being able to be referenced by defined assemblies as being able to reference code in the folder Plugins. After many hours trying to get assembly definitions to work I realize that this is wrong, only plugins, i.e. pre built dll:s work this way.

    But that got me thinking, if user defined assemblies could reference Assembly-CSharp-firstpass (or its editor counterpart for editor only scripts) wouldn't that solve all the problems with e.g. Editor folders in asset store packages? You could just copy all asset store stuff into Plugins folder, making it compile into firstpass and then reference it from your own assemblies.
     
  25. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    265
    2019: After adding asmrefs to a couple of projects, and to a couple of assets ... I discovered the major design mistakes in the original implementation, and found this thread while trying to figure out what I'm missing - why is this shiping when it doesn't seem to fully work? Reading the thread I came to the obvious conclusion: give up. These cannot be sensibly supported in plugins, it's obvious why asset-store authors aren't using them, and there's no point in developers using them either. The main use-cases are projects so obscenely large they have huge compile-times - but that's better solved already by using external compilation! (which still works, and works better than this new asmrefs stuff).

    Like others said back in 2017 (!), @karl_jones idealistic view of "Everyone will change all 3rd party code and give it to you for free" doesn't reflect reality, and the alternative of "Ruin your project structure and create dependency-hell because all the Editor scripts lose their folder-based namespacing that's core to C#" strikes me as an even worse idea for code-quality/project-cleanliness.

    Disappointed that asmrefs are still a "nice prototype" that Unity apparently hasn't got around to finishing a v1.0 implemention of yet :(.
     
  26. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    433
    @a436t4ataf Asset Store authors are more likely "not using them" because migration is still in progress. I know a few asset authors who actually do so, and do so well: e.g. UniRx, Zenject.

    Also what do you mean it cannot be "sensibly" supported? We used it in different ranges with projects from 20 asmdefs up to 120 asmdefs and it is pretty easy to recreate what the the original 4 assemblies did.

    Also "core to C#" is a bit strict. It is a guideline and I've seen and used folders to be excluded as namespace providers for different reasons.

    However, I can only repeat myself - there are major drawbacks and problems and I am not happy with the system as it is, but it is by far not as "unuseable" as you describe it is far from reality.
     
    a436t4ataf likes this.
  27. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    265
    Mostly: Asmdefs are *nearly* a good solution to a set of important problems, but feel like they were rushed through without seriously considering the consequences (especially: ignoring the vast amount of legacy code that becomes incorrect through no fault of its own).
     
    MNNoxMortem likes this.
  28. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    274
    If I could set up the references to firstpass, editor-firstpass etc in assemblies then I think they would work perfectly. I would not have to go through all the editor folders of assets from store as they would already be in the editor-firstpass and I could set up references as I saw fit.

    @karl_jones is this something that is doable? I am probably missing a lot of technical hurdles I don't even know about :)
     
  29. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    This may be possible with the new Assembly Definition Reference Files. Ill take a look tomorrow.

    Edit:

    It's not possible with the current implementation(which has almost landed in 2019.2) however we will look at adding support in the future after we land the asmref support.
     
    Last edited: Feb 4, 2019
    MNNoxMortem and Mikael-H like this.
  30. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    274
    If something like this became possible it would make me so happy! :) That would mean you could actually use assembly definitions even in legacy projects. It would bring much needed order to some stuff at work.

    Thanks for taking the time to read my humble suggestion, I really appreciate it!
     
    karl_jones likes this.
  31. mobilfactory

    mobilfactory

    Joined:
    Nov 11, 2014
    Posts:
    2
    error CS1069: The type name 'Registry' could not be found in the namespace 'Microsoft.Win32'. This type has been forwarded to assembly 'Microsoft.Win32.Registry, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' Consider adding a reference to that assembly.

    how can I add that library to 'Assembly Definition References'?
    I can't find it
     
  32. Kamyker

    Kamyker

    Joined:
    May 14, 2013
    Posts:
    85
  33. AmitSuri

    AmitSuri

    Joined:
    Sep 26, 2017
    Posts:
    21
    Hope someone will create an Asset Store package and call it "Simple / Automatic ASMDEF Creator".
     
  34. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    3,551
    2019.2 beta is now out and includes the new assembly definition reference(asmref) files feature. This will let you add out of branch files to an existing asmdef. So if you have your Editor folders included with all your scripts you can now pop an asmref file into each of the Editor folders, with a reference to a master asmdef and they will now all be compiled into the chosen asmdef. give it a try :)
     
    Last edited: May 10, 2019
  35. Wriggler

    Wriggler

    Joined:
    Jun 7, 2013
    Posts:
    83
    Hey Karl, this sounds like a great step in the right direction. Thanks for sharing!

    Ben
     
    karl_jones likes this.
  36. Ash-Blue

    Ash-Blue

    Joined:
    Aug 18, 2013
    Posts:
    95
    I wrote a script that will inject a reference into an `Editor` folder. This was really useful for my project as it has over 100 nested editor folders due to TDD. Hopefully this saves somebody else some time. PS Make sure to backup for using something like this.


    Code (CSharp):
    1. using System.IO;
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. namespace CleverCrow.DungeonsAndHumans.Utilities.Editors {
    6.     public static class AsmdefGenerator {
    7.         [MenuItem("Tools/Create Assembly Definition Files")]
    8.         public static void CreateAssemblyReferences () {
    9.             var generator = new AsmDefReferenceGenerator(
    10.                 $"{Application.dataPath}/DungeonsAndHumans",
    11.                 new [] {
    12.                     new AsmdefReference {
    13.                         assemblyDefinitionPath = "Assets/DungeonsAndHumans/Scripts/Editor/DungeonsAndHumans.Editors",
    14.                         folderName = "Editor",
    15.                         referenceName = "DungeonsAndHumans.Editors",
    16.                     },
    17.                 }
    18.             );
    19.  
    20.             generator.CreateReferences();
    21.         }
    22.     }
    23.  
    24.     public class AsmdefReference {
    25.         public string assemblyDefinitionPath;
    26.         public string folderName;
    27.         public string referenceName;
    28.     }
    29.  
    30.     public class AsmDefReferenceGenerator {
    31.         private readonly string _root;
    32.         private readonly AsmdefReference[] _referenceFolders;
    33.  
    34.         public AsmDefReferenceGenerator (string root, AsmdefReference[] referenceFolders) {
    35.             _root = root;
    36.             _referenceFolders = referenceFolders;
    37.         }
    38.  
    39.         public void CreateReferences () {
    40.             Debug.ClearDeveloperConsole();
    41.  
    42.             foreach (var referenceFolder in _referenceFolders) {
    43.                 var assemblyDefinitionId =
    44.                     AssetDatabase.AssetPathToGUID($"{referenceFolder.assemblyDefinitionPath}.asmdef");
    45.                 Debug.Log($"assemblyDefinitionId: {assemblyDefinitionId}");
    46.  
    47.                 var folders = GetFolders(referenceFolder.folderName);
    48.                 Debug.Log(string.Join(" \n", folders));
    49.  
    50.                 foreach (var folder in folders) {
    51.                     var file = File.CreateText($"{folder}/{referenceFolder.referenceName}.asmref");
    52.                     file.Write($"{{\"reference\": \"GUID:{assemblyDefinitionId}\"}}");
    53.                     file.Close();
    54.                 }
    55.  
    56.                 AssetDatabase.Refresh();
    57.             }
    58.         }
    59.  
    60.         private string[] GetFolders (string folder) {
    61.             return Directory.GetDirectories(_root, folder, SearchOption.AllDirectories);
    62.         }
    63.     }
    64. }
    65.  
     
    Mikael-H and Alexees like this.