简体   繁体   中英

unity assetbundle loadasset type

I am having issue with the asset bundle from unity. I have a bundle with multiple assets in it with the same name, but different extension, like bonus.png bonus.prefab.

When I try to instanciate a prefab named bonus, the assetBundle.LoadAssets("bonus") function doesnt return me a gameobject like it usuallly do. This seems to be happening only if i have multiple asset with the same name.

AssetBundleRequest request = assetBundle.LoadAssetAsync(m_ObjectsToPool[i].m_Name, typeof(GameObject));
        yield return request;
        GameObject prefab = request.asset as GameObject;

        if (prefab != null)
        {
            PoolManager.Instance.AddLoadedPrefabToPool(prefab, m_ObjectsToPool[i].m_Name, null, m_ObjectsToPool[i].m_Amount);
        }

But if i call loadallassets(typeof(GameObject)) and then use a for loop, i can find my asset and instanciante it properly. but that is just a dirty way of doing it.

You should be able to load assets of different types with the same name.

What version of Unity are you using?

Your code above looks correct (except for the typo calling it LoadAssetAsync?), and we don't know for sure it is failing to enter the if() statement?

The following worked for me on Unity 4.5.5f1

  1. Added ExportAssetBundles.cs context menu script to my Unity build from Unity Docs

  2. Created something to export

    • found a JPG dragged it in and named it "marble.jpg"
    • created a cube, named it "marble" and dragged it into project to create a prefab
    • created a material, named it "marble", added the jpg and dragged it onto the cube, pressed apply.
  3. Hilighted all 3 and exported asset bundle using "Build Assets From Selection - Track Selection" and saved it to "c:\\temp\\marble.unity3d"

  4. Added a script to load that asset bundle on start (similiar to yours):

     using UnityEngine; using System.Collections; public class BundleTest : MonoBehaviour { void Start () { StartCoroutine(StartCo()); } IEnumerator StartCo() { string url = "file://c:\\\\temp\\\\marble.unity3d"; WWW www = new WWW(url); yield return www; AssetBundle bundle = www.assetBundle; AssetBundleRequest request = bundle.LoadAsync ("marble", typeof(GameObject)); yield return request; Debug.Log ("loaded asset: " + request.asset.ToString()); GameObject prefab = request.asset as GameObject; GameObject go = (GameObject)Instantiate(prefab); bundle.Unload(false); www.Dispose(); } } 
  5. Ran Unity and verified I see the game object correctly.

It used to work when I was on unity 4.6, but I am now using the beta 5.0.17. And no its not a typo, it is really laodassetasync I have, I also tried with loadasset only with the same result. Right now I am using

var allAssets = assetBundle.LoadAllAssets(typeof(GameObject));
    for (int i = 0; i < m_ObjectsToPool.Count; i++)
    {
        bool found = false;
        for (int j = 0; j < allAssets.Length; j++)
        {
            if (allAssets[j].name == m_ObjectsToPool[i].m_Name)
            {
                PoolManager.Instance.AddLoadedPrefabToPool((GameObject)allAssets[j], m_ObjectsToPool[i].m_Name, null, m_ObjectsToPool[i].m_Amount);
                found = true;
                break;
            }
        }

        if (!found)
        {
            Debug.Log(string.Format("{0} object could not be found in assetbundle", m_ObjectsToPool[i].m_Name));
        }
    }

and it is working, but i dont really like this way of doing it.

Having same issue with Unity 5.1, I've found this solution: Besides refering asset by base name (no directory, no extension parts of path), you can also use full relative path (including file extension, relative to project root).

Let's say I've got bundle created from directory Assets/Bundle , it contains following files:

  • Prefabs/Box.prefab
  • Prefabs/Box2.prefab
  • Models/Box.fbx
  • Materials/Box.mat
  • Textures/Box.png

So the documented way of loading prefab that fails in our cases is

// May return nulll
bundle.LoadAsset<GameObject>("Box")

And this is the not documented way that's working correctly in our case

bundle.LoadAsset<GameObject>("assets/bundle/prefabs/box.prefab")

If you are not sure what is the correct asset name you should use for LoadAsset , you can use following code to list all asset names in bundle

string[] assets = bundle.GetAllAssetNames();
foreach (string asset in assets)
{
    Debug.Log(asset);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM