Search Unity

Exporting/Resolving Script References in AssetBundles

Discussion in 'Scripting' started by mikewarren, Jun 5, 2015.

  1. mikewarren

    mikewarren

    Joined:
    Apr 21, 2014
    Posts:
    109
    I've seen several threads regarding the exporting and importing of precompiled script code (assemblies) through asset bundle text assets. I've successfully done both using the documentation and examples on the forum.

    However, has anyone ever used an assembly loaded at run time through an asset bundle to resolve script references contained in a scene that was also loaded through an asset bundle? (Retaining script parameters in the scene.)

    I'm creating a Unity based visualization application. It does little more than allow users to navigate through a virtual scene and provide some basic interaction functionality. I'd like users to be able to generate their own content in the Unity Editor (a separate project) and then export that content (scenes) in a way that the visualization application can ingest and display. AssetBundles seem like the way to do that. I can do that now, and it works fine. The problem is that if an object has a script attached to it (maybe to make it move or perform some behavior), the script reference can't be resolved in the visualization application.

    So, in addition to the Scene Bundle, the editor script I've written also creates an Asset Bundle that contains the precompiled script code. I need to figure out how to load that bundle asset into a .Net assembly; then, find and resolve the missing script references in the Scene Bundle.

    Anyone done this?

    Here are some issues I've discovered.
    • Generating/Loading asset bundle script assemblies
      • My original thought was that the Editor already compiles the scripts for me and puts them in the library (Assembly-CSharp). Why not just copy that into the Assets directory with a .bytes extension, mark it for inclusion in a bundle, and build. You can do all that from an editor script and it works.
        • The problem is that the .Net Assembly class won't load in the visualization application. I'm pretty sure it's because the manifest of the incoming assembly is named Assembly-CSharp; and, the AppDomain of the application already has an Assembly named Assembly-CSharp. In fact the Load method doesn't throw an error, it just doesn't load the new assembly, and it returns a reference to the existing Assembly-CSharp Assembly.
        • I tried creating a new AppDomain and loading the bundle assembly into that. It didn't work, but I don't have much experience at that level.
      • I can recompile the content project with a different assembly name using a custom Visual Studio or MonoDevelop project.
        • The assembly will load in the visualization application.
        • But, I need to manually find and resolve script references. How?
        • It's onerous for content developers (not software engineers). Can the process be automated with existing Unity tools?
    • Resolving script references.
      • How do I find an unresolved script references in a scene at run time?
      • How do I resolve it? Can the script assembly be loaded first (so that references will be resolved when the scene is loaded later)?
      • (If possible) Would it help if Unity could build the content script assembly with a custom name (maybe the name of the project)? So, the assembly would be something like MyProject (MyProject.dll).
        • The name wouldn't clash with the visualization application when the assembly was loaded from the bundle.
        • And scripts contained in the content project would reference the MyProject assembly already. (Would they?) If I loaded that assembly into the visualization app first, would script references resolve (automatically)?
    Sorry for the long post. I'm hoping someone has some ideas.

    Mike
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
  3. mikewarren

    mikewarren

    Joined:
    Apr 21, 2014
    Posts:
    109
    Thank you for the link. Yes, I'm well familiarized with it.

    My problem isn't with creating asset bundles containing scripts, or with loading them and converting them back to .Net Assemblies (except when the Assembly is Assembly-CSharp - different issue). I done both successfully.

    My issue is with using Types/Components contained within an Asset Bundle to resolve script references in a scene also loaded from a bundle. All the examples I've seen, including the manual page, show creating and attaching a new instance of a component.

    So, I need a way to search scenes / objects loaded in a scene bundle, find missing script references, locate the corresponding component in a script bundle, and instantiate an instance of the script component. I need to retain parameters for the script that were part of the scene bundle.

    I hope that is clearer.
     
  4. mikewarren

    mikewarren

    Joined:
    Apr 21, 2014
    Posts:
    109
  5. drew55

    drew55

    Joined:
    Dec 13, 2017
    Posts:
    44
    Hi Mike -

    Old thread, but I'd love to see where this is at and am working on this as well. Do you have any code or sample projects that you'd be willing to share? That'd save a TON of time and would really helpful for this 501c3 charity project I'm working on.

    Thanks,
    Drew
     
  6. mikewarren

    mikewarren

    Joined:
    Apr 21, 2014
    Posts:
    109
    I'm afraid I'm going to disappoint.
    I think something has changed since I worked on this. See the following thread.

    https://answers.unity.com/questions...time.html?childToView=1580448#comment-1580448

    It's my recollection that at one time, if your script was defined in an assembly (like a plugin) you could load the assembly manually before loading the (asset bundle) scene and the system would find the script reference. I think this was more of an artifact than an intentional design decision. I think the referencing system is more complicated now, and that trick no longer works. At least, I couldn't get it to work the last time I tried.

    Good luck.
     
    Last edited: Mar 23, 2020
  7. drew55

    drew55

    Joined:
    Dec 13, 2017
    Posts:
    44
    Thanks for getting back, Mike!

    Indeed, our system currently uses what you describe: a .NET dll that links w/ the deployed app/project and also ships in the content SDK. As you know, this allows 3rd parties/users to attach the project's MonoBehavior sub classes, put content in asset bundles, and rely on the deployed app's DLL to deserialize and instantiate them, etc. Your point stands about this more likely being an artifact than an intended feature. That said, the Unity Technology folks hopefully get that this kind of functionality is critical for any title that is looking to put a SDK out there. Indeed, it's a tall order to be pulling off dynamic code loading, but they also hopefully get what a mega feature this is (and how it starts to make Unity an OS/platform more than it is a gaming engine!). Related: https://forum.unity.com/threads/assetbundle-migration-addressables-across-projects.793827/

    I can share about our project if you're interested -- we're using Unity to make an integrated productivity/collaboration suite with a go p2p backend (with distributed and secure storage).

    It's called PLAN -- https://plan-systems.org

    My colleagues and I have quite a history, starting with U.S. DoD intel and logistics. This is no game and world events are showing this kind of tech is NEEDED. Meanwhile, the best tools for teams out there is stuff like Slack, Discord, and Teams?? Enterprise tech ppl think 3D tech is for games and offer stuff like Three.js as if that even compares to Unity or Unreal. Adorable, right? Things are changing, however...
     
    Last edited: Mar 24, 2020