Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Referenging package dll's in external projects

Discussion in 'Package Manager' started by snacktime, Jan 8, 2019.

  1. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,437
    So I have a C# project that generates a dll that is shared by client and server. I reference libraries like mathematics in this project. I've been referencing it from ScriptAssemblies, so I know the reference is always up to date with the package Unity is using.

    But Unity complains about that saying it's not able to reference the package. It eventually sorts it out as there are no compile errors. So I'm assuming the package dll's are at some point either built or copied to ScriptAssemblies during start or reload?

    So what is the correct way to reference packages from other projects?
     
  2. maximeb_unity

    maximeb_unity

    Unity Technologies

    Joined:
    Mar 20, 2018
    Posts:
    144
    Hi @snacktime,

    You got the gist of it. The assemblies under ScriptAssemblies are generated by the Unity compilation pipeline.

    Some context: scripts in packages are compiled with assembly definitions, which play a role in the compilation pipeline similar to Visual Studio projects (e.g. .csproj). When assemblies are compiled from assembly definitions and their scripts, the generated DLLs are copied to the ScriptAssemblies directory.

    When a project is first opened, that folder does not exist (unless it was put under source control, which is strongly discouraged). It gets populated with the assemblies built from code in packages and your project Assets. In addition, there are situations where they will be rebuilt and re-copied, which might provide a tiny window where the DLL files are missing.

    In addition, we don't currently support pre-compiled assemblies (DLL files built outside Unity, and imported from your Assets or in packages) referencing assemblies built with assembly definitions. While this can work, there will be situations where the precompiled DLL cannot has TypeLoadExceptions (for instance) as a referenced DLL has not been compiled yet; this seems to be your case, if I understand correctly.

    So assuming both your client and server are built with Unity, the simplest solution is to also use assembly definitions with the scripts directly under your Unity project, rather than building it outside of Unity. Since assembly definitions declare references to other assembly definitions, the compilation order is guaranteed, and it also ensures that your DLL won't be loaded without its dependencies being compiled first.
     
    pahe4retro likes this.
  3. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    2,437
    Thanks for the info. The server is not Unity. While you could put the shared code under Unity in cases like this and copy dll's to the server, it's generally problematic. Like if you actually do unit testing the compile/test flow in VS is clearly superior and faster. Unity also has no first class support for Nuget and we make use of things like T4 templates and also build pipeline hooks.
     
  4. astorms

    astorms

    Joined:
    Jan 31, 2018
    Posts:
    26
    Are there plans to support pre-compiled assemblies referencing assemblies built with assembly definitions? This would be extremely valuable for our team, for reasons similar to what @snacktime mentioned.
     
  5. maximeb_unity

    maximeb_unity

    Unity Technologies

    Joined:
    Mar 20, 2018
    Posts:
    144
    Hi @astorms,

    Use cases like yours are not that rare, so this is something we're looking into. However I cannot make any guarantees about this nor provide any ETA at this time.
     
  6. farshidhss2

    farshidhss2

    Joined:
    Sep 19, 2019
    Posts:
    2
    Is there any update on this? we have a very similar use case.
     
  7. pahe4retro

    pahe4retro

    Joined:
    Aug 13, 2019
    Posts:
    16
    An update would be great @maximeb_unity . We're currently facing a similar problem where we're referencing a generated package dll in our custom DLL.

    I've posted a thread here, but never got a response. Now that I found this post, I at least know that it's a common problem.

    Edit:
    I would also take an alternative approach to the problem. All I need to achieve is to get the (Addressables) package scripts into my visual studio project, without copying them in the best case (which is what we're doing at the moment and which is pain af!)
     
    Last edited: Nov 8, 2019
  8. pahe4retro

    pahe4retro

    Joined:
    Aug 13, 2019
    Posts:
    16
    So, I spend the weekend with the problem and I found a kinda solution at least to one of our problems:

    Our project structure looks like:
    Code (csharp):
    1. - <logic solution>.sln
    2. -- <logic A>.csproj   (no unity references)
    3. -- <logic B>.csproj   (no unity references)
    4. -- ...
    5. -- <logic Y>.csproj   (unity referenced)
    6. -- <logic Z>.csproj   (unity and unity packages referenced)
    7.  
    8. - Unity Project
    9. -- Assets
    10. --- Plugins
    11. -- Packages
    12. --- <package1>   (e.g. com.unity.ugui)
    13. --- ...
    All created DLLs are copied into the Unity projects Plugins folder. This works fine for all DLLs except for Z. Z needs one of the packages (e.g. com.unity.ugui) and as we can't simply reference the automatically generated DLL from the UnityProject/Library/ScriptAssemblies folder we come to our problem.

    The solution to this problem is to exclude the logic Z project from the logic solution, make a custom package for the UPM out of it and add the dependency to the package then. This would lead to an updated structure like:

    Code (csharp):
    1. - <logic solution>.sln
    2. -- <logic A>.csproj   (no unity references)
    3. -- <logic B>.csproj   (no unity references)
    4. -- ...
    5. -- <logic Y>.csproj   (unity referenced)
    6.  
    7. - Unity Project
    8. -- Assets
    9. --- Plugins
    10. -- Packages
    11. --- <package1>   (e.g. com.unity.ugui)
    12. --- <package logic Z>   (added dependency to com.unity.ugui)
    13. --- ...
    Now this leaves the only problem open when Z also needs to scripts from the Unity project (e.g. when importing a plugin from the Assetstore which comes with scripts you want to reference). You can't simply convert the imported plugin into a package and even if you move it outside of the project, create a custom package file for it,... Z can't reference to other local packages at the moment, as the UPM isn't able to setup such local dependencies.

    Would be nice to know if and when the UPM would allow those local dependencies, but actually I'd prefer if packages would compile into DLLs which then could be reference from my outside DLL projects.