Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

[ADVANCED USE CASE] AssetBundles and dynamically loaded assemblies

Discussion in 'Experimental Scripting Previews' started by bdovaz, Aug 30, 2019.

  1. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,053
    @JoshPeterson

    I thought on posting this on "Scripting" subforum but it's spammed with newbie questions and it would get lost so I post it here hoping that some Unity staff member will read it.

    I'll try to explain my case as detailed as possible.

    I have 2 projects:

    1. Main project:
    - Has a framework (scripts) published as packages with scope registries so then it can be retrieved with Package Manager.
    - Loads Asset Bundles referencing this scripts (framework) and new scripts extending this framework, loaded with "Assembly.Load(assembly);".

    2. Asset Bundle project:
    - Will install that Unity Package Manager packages provided by Main project.
    - A third party will use the framework on two cases:
    a. Using the provided scripts by the framework (installed by UPM).
    b. Extending this framework and creating it's own *.asmdef referencing the framework.
    - Will create an asset bundle optinally with (optionally) the assembly (*.dll) with this extended code.

    I see that in "Library/ScriptAssemblies" there are the main (Assembly-CSharp) and *.asmdef compiled assemblies. I created an *.asmdef with code (referencing the framework) as an example and copied the generated *.dll in that folder and use it in the main project without any issues but I'm afraid that I'm not correctly using it because that assemblies are compiled for Editor (UNITY_EDITOR) and not for Player (!UNITY_EDITOR && UNITY_STANDALONE_WIN64). So if I copy that *.dll it will crash on an executable if it has unity editor API usages.

    I also tried investigating this recently added "AssemblyBuilder" API to compile them myself but it's really hard to use it in my case because I would need to transverse all dependency tree for correctly compiling the final *.dll along all the assembly dependencies. Also, I don't know if the assetbundle will correctly reference MonoBehaviour scripts from that *.dll as it's a different one than "Library/ScriptAssemblies".

    Can you help me or point me to another coworker that would clarify this use case?
     
    Last edited: Aug 31, 2019
  2. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,938
    I'm not able to help with this, but I'll see if I can find someone with more knowledge about this.
     
  3. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    Bshsf_9527 likes this.
  4. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,053
    Have you read my post closely? I'm saying that it works but that I'm using a dll that it's compiled with UNITY_EDITOR directive and I want to use the runtime dll.
     
  5. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    Sorry, I did but it seems I am a little lost on either your setup or what you are trying to achieve. So setting aside any discussion of "Assembly.Load(assembly);" and any quarks around that, here's my simplified understanding, and tell me if this is correct:

    1. You have a main project which contains your code that you publish in UPM.
    2. Users install this package via UPM and extend it in their own assembly.
    3. The Problem: "Something" is being done with the assemblies in "Library/ScriptAssemblies" that doesn't work because of incorrect runtime defines.

    Now if my simplified understanding of the root of the problem is correct, there's a few things you could try. As you mentioned building the dll's using AssemblyBuilder is one option. Another one that we use for Scriptable Build Pipeline is the PlayerBuildInterface.CompilePlayerScripts API which builds the final player ready dlls into a specified output folder.
     
  6. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,053
    I didn't know about PlayerBuildInterface API.

    Researching I realized that by calling "BuildAssetBundles" method before generating the AssetBundle itself, compiles all the assemblies in "Player" mode so intercepting in an event the compilation finished step I can then access the list of assemblies, get the one I'm interested in and copy it wherever I want.

    So I ended doing this:

    Code (CSharp):
    1. CompilationPipeline.compilationFinished += OnCompilationFinished;
    2.  
    3. AssetBundleManifest assetBundleManifest = BuildPipeline.BuildAssetBundles(assetBundlesFolderPath, buildMap, options, BuildTarget.StandaloneWindows64);
    Code (CSharp):
    1. private void OnCompilationFinished(object sender) {
    2.     CompilationPipeline.compilationFinished -= OnCompilationFinished;
    3.  
    4.     var assemblies = CompilationPipeline.GetAssemblies(AssembliesType.Player);
    5.  
    6.     var assembly = assemblies.FirstOrDefault(e => e.name.Equals("MY_ASSEMBLY_NAME"));
    7.  
    8.     File.Copy(assembly.outputPath, "MY_DESTINATION_PATH");
    9. }
    10.  
    It seems that I'm able from my main project to:
    - Load the assembly with "Assembly.Load()";
    - Load the AssetBundle.

    It correctly references the scripts inheriting from MonoBehaviour. No missing MonoBehaviour warnings.
     
  7. Bshsf_9527

    Bshsf_9527

    Joined:
    Sep 6, 2017
    Posts:
    43
    I like all the discuss here, helps me a lot, and from now on, I get a very important information: Serializable Type Loaded with Assembly.Load can not corretly assign instance as well as its instance members, which confuse me a lot these days.
    and , holp your script team solve this issue soon as so many years have had passed .
    also, holp this repo can help someone : https://github.com/Bian-Sh/Assemblies-Hotfix-Toolkit
     
  8. Bshsf_9527

    Bshsf_9527

    Joined:
    Sep 6, 2017
    Posts:
    43
    dear sir,is ther any update ?