Search Unity

Understand 'Including scripts in AssetBundles'

Discussion in 'Scripting' started by Clodo, Oct 30, 2014.

  1. Clodo

    Clodo

    Joined:
    Dec 27, 2013
    Posts:
    40
    I hope someone will have the patience to understand my english :p.

    My final objective is to allow friends to create levels of my little game within Unity, without give it all source-code (many of them are assets that i buy on the Store).

    The idea is encapsulate all the game objects (camera, player etc) and some code in a single prefab,
    export it as Core.unity3d and share it. Portability between platforms doesn't matter now.

    If a friend want to create a level, it create a new project, import an .unitypackage that contain a script "LoadCore" that
    load the Core.unity3d and instantiate it.

    So, i try that.


    Second part:

    • I create an empty project called "MyLevel".
    • I create an empty gameobject and i create the script "LoadCore.cs":

    Code (CSharp):
    1.  
    2.         string urlAssets = "<pathto>/Core.unity3d";
    3.         WWW wwwAssets = new WWW(urlAssets);    
    4.         yield return wwwAssets; // Wait for download to complete       
    5.        
    6.         AssetBundle bundleAssets = wwwAssets.assetBundle; // Load and retrieve the AssetBundle
    7.  
    8.        
    9.        
    10.         // Load the object asynchronously
    11.         AssetBundleRequest request = bundleAssets.LoadAsync("MyCore", typeof(GameObject));
    12.         // Wait for completion
    13.         yield return request;
    14.        
    15.         Instantiate(request.asset);
    16.        
    17.         // Unload the AssetBundles compressed contents to conserve memory
    18.         bundleAssets.Unload(false);
    19.         // Frees the memory from the web stream
    20.         wwwAssets.Dispose();
    21.  
    When i run the level, it load correctly my bundle, and prefab MyCore are added to the scene.
    But say "The referenced script on this Behaviour is missing!".
    I view the MyCore gameobject in the hierarchy, with the yellow warning about the missing script "MyCore.cs"


    Ok, this is expected, i understand it's because Assets Bundle cannot contain script.

    Next step, add scripts using Reflection, discussed here: http://docs.unity3d.com/Manual/scriptsinassetbundles.html

    • In my "Core" project i add the "Assembly-CSharp.dll" generated by VS2010, named as "Assembly-CSharp.dll.bytes".
    • I launch the ExportAssetBundles script and recreate my "Core.unity3d". I'm sure it contain MyCore prefab and the assembly in TextAsset format.

    Second part:

    • In my "MyLevel" project i change "LoadCore.cs" script: (only added the part between // ADDED PART )

    Code (CSharp):
    1.  
    2.         string urlAssets = "<pathto>/Core.unity3d";
    3.         WWW wwwAssets = new WWW(urlAssets);    
    4.         yield return wwwAssets; // Wait for download to complete       
    5.        
    6.         AssetBundle bundleAssets = wwwAssets.assetBundle; // Load and retrieve the AssetBundle
    7.  
    8.        
    9.         // START ADDED PART
    10.         TextAsset txt = bundleAssets.Load("Assembly-CSharp.dll", typeof(TextAsset)) as TextAsset;
    11.         Debug.Log(txt.bytes.Length.ToString());    
    12.         var assembly = System.Reflection.Assembly.Load(txt.bytes); // Load the assembly
    13.         // END ADDED PART
    14.        
    15.        
    16.         // Load the object asynchronously
    17.         AssetBundleRequest request = bundleAssets.LoadAsync("MyCore", typeof(GameObject));
    18.         // Wait for completion
    19.         yield return request;
    20.         Instantiate(request.asset);
    21.        
    22.         // Unload the AssetBundles compressed contents to conserve memory
    23.         bundleAssets.Unload(false);
    24.         // Frees the memory from the web stream
    25.         wwwAssets.Dispose();
    26.  
    I'm sure that Assembly is serialized in the bundle and loaded correctly: 'assembly' variable is loaded and valid.

    But i still have the "The referenced script on this Behaviour is missing!" error.

    What i'm wrong? I don't have any ideas about what i can try.

    Generating two different .unity3d bundle (one with the assembly, one with the prefab) and load for first the assembly and after the prefab, don't change anything.

    Thanks for any advice.
     
  2. Clodo

    Clodo

    Joined:
    Dec 27, 2013
    Posts:
    40
    Some words about why i'm looking this approach.


    I'm building a simple platformer game.
    I have a single prefab that contain all game engine (camera, player mesh, gui, script etc.).
    I build levels by creating a new scene for each level, delete the default maincamera, add my Core prefab and add specific level objects.
    All works well.

    Now, i want to allow my players to build levels of my game, within Unity.

    I understand i can simply export all my project in a .unitypackage and share it.
    It's a dream to do that, i will happy to release the source code of my game, i'm an open-source fan.

    But in my engine i use a lot of code not created by me, for example FX Mega Pack and Immerside Mode for Android.
    If i share .unitypackage on a public website, source-code of this assets will be public, it's not correct.

    For that, i'm looking the approach in the first post.

    Thanks for reading :p
     
  3. Ekta-Mehta-D

    Ekta-Mehta-D

    Joined:
    Feb 25, 2013
    Posts:
    24
    Hey did you get any solution ?