Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Referencing the Hydra - DLL Assemblies and Types in Asset Bundles

Discussion in 'Scripting' started by AIResearcher, Jul 3, 2011.

  1. AIResearcher

    AIResearcher

    Joined:
    Aug 23, 2010
    Posts:
    39
    I have been working on the "Downloading the Hydra" stuff of compiling scripts into assemblies and loading the assemblies and reconnecting gameObjects to their scripts.

    When an Asset Bundle is loaded and an Game Object in that bundle has a script, Unity3d looks to see if it knows about the class referenced in the script. Even though I load my C# DLL assembly before I load the Asset Bundle into memory, it is still unable to match up the names properly between my DLL and the Assets. I get the error, "The class defined in the script file named <> does not match the file name!"

    Is there a way I can load the types necessary for a given Asset Bundle somewhere where Unity3d can properly connect them? If I simply grab the System.Type from the Assembly and use AddComponent<type>( ) on the game object it has no problems connecting them.

    As a work-around, I have a script which finds a game object by string, then loads a type by string, then attaches the type to game object (using AddComponent<type>). But with that I have to detach the script in the editor and make sure to hard-code the editor-set public variables in the script. If I have multiple Game Objects using different public variables on the same script then it's a bit more complex.
     
  2. chuckrussell

    chuckrussell

    Joined:
    Oct 10, 2011
    Posts:
    2
    I know this is an old thread, but I am experiencing the same issues. Did you ever find a work around, or is there anyone else who can provide a solution?
     
  3. AIResearcher

    AIResearcher

    Joined:
    Aug 23, 2010
    Posts:
    39
    We have not found a solution to the problem.

    We did do an automate a work around for it, but it causes all kinds of problems and restrictions.

    Our work-around has one game object at root-level which is has a component which extends a 'level' component.

    We then create a new prefab based on that level component, search for all children of that level component recursively and for each script not in the standard engine core (level-specific scripts).

    We have one initialization script which records all of the necessary game objects, components, etc... in the prefab. We write out specific .cs code to initialize every child component with its proper value.

    When we load the level, we load the prefab, call it's initialization script (which sets it all up) and then instantiate the prefab.

    Current limitations (I don't remember them all), is that we do not support javascript and that because we use a prefab we can not load a disabled gameobject. Rather we have to attach a script to that gameobject which disables it on it's Activate() function.
     
  4. Several

    Several

    Joined:
    Apr 16, 2012
    Posts:
    3
    In hopes of stirring up other solutions, I'll echo the problem.

    I believe I've been wrestling with the same issue: my assembly and prefabs seem to be loading just fine, but the connection between the prefabs' Script Components and their MonoBehaviours is lost. I've tried using the same assembly to provide the MonoBehaviour in the project that I'm exporting from (instead of the C# that assembly is compiled from), but the result is the same, regardless of order loaded or whether they're in the same AssetBundle.

    I'm also exploring streaming the Scene, but have thus far only just received the same warning/error. (The script/assembly may not be getting included here though—I haven't pursued this angle very far yet.)

    I have not resorted to including the scripts in the bundle as a text, yet, but the odds of this doing anything to help Unity make the connection seem laughably slim.

    I had been considering a workaround similar to AIResearcher's, and was wondering if I could leverage the flexibility of JavaScript's for (key in object) {…} (if it works the same in 'UnityScript') to avoid writing code specific to this problem for every Script I need to load. I imagine this would incur an initial performance hit, though (if it works). I may not end up exploring this, however, as the fallback of writing a (Window-only) "shell" that treats the Unity app as an ActiveX control is looking like it may be more appropriate to the demands of the project.

    I'd love to hear if anyone else has managed to successfully load external prefabs along with their scripts, or has any additional insight into how Unity references compiled classes to Script Components.
     
  5. AIResearcher

    AIResearcher

    Joined:
    Aug 23, 2010
    Posts:
    39
    We use something similar to what you have in mind with JavaScript. It's called Introspection. We use it to grab each publically available type and interrogate to see what it is, based on what it is we initialize it accordingly in it's own script. The generation of the initialization script for each prefab is 100% automated.

    Again, there are some caveats. For instance, because it is a prefab there's no way to instantiate it while allowing it to remain disabled. In the editor this is just disabling the component or game object. So we have a script (in our core engine) which will disable on onEnable and then remove itself so it isn't called again.

    When Unity3d loads a component it grabs its type from some string, and then checks to see if that string is a currently loaded type. If there was a function that we could possibly intercept / extend that would allow us to provide our own assembly loaded types when Unity3d can't find one in it's own repository then hopefully this would take care of the entire issue.

    Something like AppDomain.CurrentDomain.AssemblyResolve to resolve assembly loads...
     
  6. AIResearcher

    AIResearcher

    Joined:
    Aug 23, 2010
    Posts:
    39
    It seems like we are almost there. We have everything we need except initialization of our modules / bundles / prefabs from the editor. I would also appreciate more insight into how Unity references compiled classes to script components and how this last hurdle may be overcome...
     
  7. tomason

    tomason

    Joined:
    Nov 6, 2010
    Posts:
    10
    We're trying to do something like this too, so I thought I'd bump the thread and let UT know there are more who want to do this.

    Our specific reason is to solve a bigger problem with Android development: It takes FOREVER to test changes on device. It would be awesome to have a way to quickly test changes on device. We'd like to be able to build a new assembly with code changes, build a new streamed scene asset bundle, and then send a message over wifi to the device to re-download the code and data, and then the device will just have to restart the game and get the changes. That would avoid the minutes of time waiting for Unity to rebuild the whole .apk and push it to device.

    But maybe there's a better way to accomplish that?

    -Tom
     
    Last edited: May 3, 2012
  8. Terikon

    Terikon

    Joined:
    Oct 12, 2012
    Posts:
    6
    Is there any progress in the thread after more than year after opening?
    We experience the same limitation - loading assembly from AssetBundle doesn't connect MonoBehaviours it contain. Unity complains that "The class defined in script file named 'XXX' does not match the file name!".
    Re-attaching scripts with GameObject.AddComponent() works, but loses all the parameter values.
     
  9. kimsama

    kimsama

    Joined:
    Jan 2, 2009
    Posts:
    166
    Bump!
     
  10. kelloh

    kelloh

    Joined:
    Mar 2, 2015
    Posts:
    29
    I hit this limitation as well, trying to add mod support to a game. Has anyone found any real workarounds in the interim?