Search Unity

Second preview build for iOS 9 On Demand Resources and App Slicing support

Discussion in 'iOS and tvOS' started by povilas, Sep 8, 2015.

  1. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    531
    Thanks for the reply. Is that because once it's added to an asset bundle it will only belong to where that bundle lives in the file system ie. and the file won't be reinstated to it's original location in the Streaming Assets folder? Also would it be possible once an asset has been loaded via asset bundle / ODR that it could be moved to the Streaming Assets folder? even if the move happens in native code.

    Sorry just trying to understand why you mentioned that the loading part would need to be native code. Thanks for your help, cheers!
     
  2. Mantas-Puida

    Mantas-Puida

    Joined:
    Nov 13, 2008
    Posts:
    1,864
    For iOS creating file and extracting video from Asset Bundle there would work (just don't forget to apply no backup flag on extracted file and I believe you would need to pick other folder). Though for tvOS it would be a problem as there is not reliable persistent storage and all your files might be wiped between two runs of your application.
     
  3. helios

    helios

    Joined:
    Oct 5, 2009
    Posts:
    308
    I cannot for the life of me figure out how to get any of this to work. Something is just not clicking, and the only resource for iOS ODR is this thread and a blog post.

    I have no problem creating asset bundles. In fact, I can do so quite easily by using the new AssetBundleGraphTool: https://bitbucket.org/Unity-Technologies/assetbundlegraphtool/

    I can't, for some reason, get any of the resource loading to work. I get an "Unable to open archive: res://bundle_0" error at this point in my code:
    Code (CSharp):
    1.         var path = "res://" + "bundle_0";
    2.         var bundle = AssetBundle.LoadFromFile(path);
    My resource collection code looks like this:
    Code (CSharp):
    1. public class BuildResources
    2. {
    3.     [InitializeOnLoadMethod]
    4.     static void SetupResourcesBuild()
    5.     {
    6.         UnityEditor.iOS.BuildPipeline.collectResources += CollectResources;
    7.         Debug.Log( "build resources: " );
    8.     }
    9.  
    10.     static UnityEditor.iOS.Resource[] CollectResources()
    11.     {
    12.         return new Resource[]
    13.         {
    14.             new Resource( "forest-collections", "AssetBundles/tvOS/bundle_0" ).AddOnDemandResourceTags( "forest-collections" )
    15.         };
    16.     }
    17. }
    Anyone know what my problem is? The bundle was built and added to /AssetBundles/tvOS. I'm running the editor script as well to create the resources. Perhaps that is what is failing? Are there any functioning demos available that strictly use simple ODR for iOS/tvOS? Preferably something that a three year old could understand.

    Thanks.
     
  4. povilas

    povilas

    Unity Technologies

    Joined:
    Jan 28, 2014
    Posts:
    427
    You should issue on demand resource request like this before accessing the asset bundle:

    Code (CSharp):
    1.  
    2. var request = OnDemandResources.PreloadAsync(new string[] { "forest-collections" } );
    3. yield return request;
    4. if (request.error != null)
    5.     throw new Exception("ODR request failed: " + request.error);
    6. var bundle = AssetBundle.CreateFromFile("res://forest-collections");
    7.  
     
  5. helios

    helios

    Joined:
    Oct 5, 2009
    Posts:
    308
    Thanks for your reply. Yea, I am doing that already - I should have pasted the full code, but I was just pointing out the line where it was failing. Is there anything else obvious I'm missing?
     
  6. helios

    helios

    Joined:
    Oct 5, 2009
    Posts:
    308
    So nothing works, even in the Editor (only Simulation Mode works). If i use a local asset server via the AssetBundleManager menu, or if i build to device, I get the same failures to load:
    Code (CSharp):
    1. Unable to open archive file: res://iOS
    2. UnityEngine.AssetBundle:LoadFromFile(String)
    3. AssetBundles.AssetBundleDownloadFromODROperation:FinishDownload() (at Assets/AssetBundleManager/AssetBundleLoadOperation.cs:100)
    4. AssetBundles.AssetBundleDownloadOperation:Update() (at Assets/AssetBundleManager/AssetBundleLoadOperation.cs:51)
    5. AssetBundles.AssetBundleManager:Update() (at Assets/AssetBundleManager/AssetBundleManager.cs:558)
    6.  
    Code (CSharp):
    1. Failed downloading bundle iOS from odr://iOS: Failed to load res://iOS
    2. UnityEngine.Debug:LogError(Object)
    3. AssetBundles.AssetBundleLoadAssetOperationFull:IsDone() (at Assets/AssetBundleManager/AssetBundleLoadOperation.cs:351)
    4. AssetBundles.AssetBundleLoadOperation:MoveNext() (at Assets/AssetBundleManager/AssetBundleLoadOperation.cs:24)
    5. UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
    This happens even in the supplied demo scenes. There either is something core that I'm not comprehending, or this just doesn't work in 5.4.2.
     
    Last edited: Nov 1, 2016
  7. helios

    helios

    Joined:
    Oct 5, 2009
    Posts:
    308
    Anyone? I'm pretty desperate here, and not sure what I'm doing wrong.
     
  8. spottedzebra

    spottedzebra

    Joined:
    Oct 26, 2013
    Posts:
    39
  9. jugnu

    jugnu

    Joined:
    Jul 17, 2012
    Posts:
    28
    Hi,

    I am doing ODR using Asset Bundle Manager from bitbucket. I am making large prefab containing complete canvas hierarchy & it contains all the animations & sounds in it. When i initially tested it was working fine and showing 22 mb on test flight. Initially i was using uncompressedAssetBundle for building the assets. Then i started making more prefabs for all the mini games and some prefabs had reference/connection from resources folder and when i uploaded the build to testflight it was showing 224 mb. And yes when i started making more prefabs i changed the build option to chunkbasedAsset from uncompressedAssetBundle. it was showing correct in xcode in Resource Tags tab... like prefabs sized were 4 mb, 7 mb, 10 mb.. etc etc.

    I read somewhere if u put any resource in Resources Folder and load it from there it goes with the binary or executable. So then i removed all the references from those prefabs, basically i removed the asset tags from it. But to my surprise when i loaded it after that to the test flight it size increased to 280 mb.

    I am using the below script for loading the prefab for ODR and Asset Bundle Manager from bitbucket.

    PS: I am using scripting backend as IL2CPP and Architecture universal.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using AssetBundles;
    5. public class LoadResources : MonoBehaviour
    6. {
    7.      public const string AssetBundlesOutputPath = "/AssetBundles/";
    8.      public string assetBundleName;
    9.      public string assetName;
    10.      AssetBundleLoadAssetOperation request;
    11.      // Use this for initialization
    12.      IEnumerator Start()
    13.      {
    14.          yield return StartCoroutine(Initialize());
    15.          // Load asset.
    16.          yield return StartCoroutine(InstantiateGameObjectAsync(assetBundleName, assetName));
    17.      }
    18.      // Initialize the downloading URL.
    19.      // eg. Development server / iOS ODR / web URL
    20.      void InitializeSourceURL()
    21.      {
    22.          // If ODR is available and enabled, then use it and let Xcode handle download requests.
    23.          #if ENABLE_IOS_ON_DEMAND_RESOURCES
    24.          if (UnityEngine.iOS.OnDemandResources.enabled)
    25.          {
    26.              Debug.Log("Inside Initialize source URL ODR Enabled");
    27.              AssetBundleManager.SetSourceAssetBundleURL("odr://");
    28.              return;
    29.          }
    30.          #endif
    31.          #if DEVELOPMENT_BUILD || UNITY_EDITOR
    32.          // With this code, when in-editor or using a development builds: Always use the AssetBundle Server
    33.          // (This is very dependent on the production workflow of the project.
    34.          //      Another approach would be to make this configurable in the standalone player.)
    35.          Debug.Log("Inside Initialize source URL  Set Development Asset Bundle Server");
    36.          AssetBundleManager.SetDevelopmentAssetBundleServer();
    37.          return;
    38.          #else
    39.          Debug.Log("Inside Initialize source URL  Application data path");
    40.          // Use the following code if AssetBundles are embedded in the project for example via StreamingAssets folder etc:
    41.          AssetBundleManager.SetSourceAssetBundleURL(Application.dataPath + "/");
    42.          // Or customize the URL based on your deployment or configuration
    43.          //AssetBundleManager.SetSourceAssetBundleURL("http://www.MyWebsite/MyAssetBundles");
    44.          //
    45.          return;
    46.          #endif
    47.      }
    48.      // Initialize the downloading url and AssetBundleManifest object.
    49.      protected IEnumerator Initialize()
    50.      {
    51.          // Don't destroy this gameObject as we depend on it to run the loading script.
    52.          DontDestroyOnLoad(gameObject);
    53.          InitializeSourceURL();
    54.          // Initialize AssetBundleManifest which loads the AssetBundleManifest object.
    55.          var request = AssetBundleManager.Initialize();
    56.          if (request != null)
    57.              yield return StartCoroutine(request);
    58.      }
    59.      protected IEnumerator InstantiateGameObjectAsync(string assetBundleName, string assetName)
    60.      {
    61.          // This is simply to get the elapsed time for this phase of AssetLoading.
    62.          float startTime = Time.realtimeSinceStartup;
    63.          // Load asset from assetBundle.
    64.          //AssetBundleLoadAssetOperation request = AssetBundleManager.LoadAssetAsync(assetBundleName, assetName, typeof(GameObject));
    65.          request = AssetBundleManager.LoadAssetAsync(assetBundleName, assetName, typeof(GameObject));
    66.          if (request == null)
    67.              yield break;
    68.        
    69.          yield return StartCoroutine(request);
    70.          // Get the asset.
    71.          Debug.Log ("Request Successful");
    72.          Debug.Log(request.GetAsset<GameObject>().name);
    73.          GameObject prefab = request.GetAsset<GameObject>();
    74.          if (prefab != null)
    75.          {
    76.              GameObject obj = GameObject.Instantiate (prefab);
    77.              Debug.Log ("Downloaded Asset");
    78.          }
    79.          // Calculate and display the elapsed time.
    80.          float elapsedTime = Time.realtimeSinceStartup - startTime;
    81.          Debug.Log(assetName + (prefab == null ? " was not" : " was") + " loaded successfully in " + elapsedTime + " seconds");
    82.      }
    83. }
     
  10. Beetxm123

    Beetxm123

    Joined:
    Mar 15, 2016
    Posts:
    1
    I have encountered the same problem, have you solved it?
     
  11. Nidhii

    Nidhii

    Joined:
    Jan 28, 2015
    Posts:
    26
    Hi I tried the project too. It isnt working for ODR. Did it work on your end eventually?