统一assetbundle loadasset类型

时间:2014-12-16 18:40:37

标签: c# unity3d assetbundle

我遇到了来自团结的资产包问题。我有一个包含多个资产的包,名称相同,但扩展名不同,如bonus.png bonus.prefab。

当我尝试设定一个名为奖金的预制件时,assetBundle.LoadAssets(“奖励”)功能并不会像我一样回报我一个游戏对象。只有当我有多个具有相同名称的资产时,这似乎才会发生。

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);
        }

但是如果我调用loadallassets(typeof(GameObject))然后使用for循环,我可以找到我的资产并正确地实例化它。但这只是一种肮脏的方式。

3 个答案:

答案 0 :(得分:1)

您应该能够加载具有相同名称的不同类型的资产。

您使用的是什么版本的Unity?

上面的代码看起来是正确的(除了输入LoadAssetAsync的错字?),我们不确定它是否输入了if()语句?

以下适用于Unity 4.5.5f1

  1. Unity Docs

  2. 向我的Unity版本添加了ExportAssetBundles.cs上下文菜单脚本
  3. 创建要导出的内容

    • 发现JPG将其拖入并将其命名为“marble.jpg”
    • 创建了一个立方体,将其命名为“大理石”并将其拖入项目以创建预制件
    • 创建了一个名为“marble”的材质,添加了jpg并将其拖到立方体上,按下了apply。
  4. 使用“从选择中构建资源 - 跟踪选择”并将其保存到“c:\ temp \ marble.unity3d”

  5. ,对所有3和导出的资产包进行预测
  6. 添加了一个脚本,可以在启动时加载该资产包(与您的类似):

    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();
      }
    }
    
  7. Ran Unity并验证我正确看到了游戏对象。

答案 1 :(得分:1)

我曾经在团结4.6上工作,但我现在正在使用beta 5.0.17。不,它不是一个错字,它真的是laodassetasync我有,我也尝试使用loadasset只有相同的结果。现在我正在使用

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));
        }
    }

它正在发挥作用,但我真的不喜欢这种做法。

答案 2 :(得分:1)

与Unity 5.1存在同样的问题,我发现了这个解决方案: 除了通过基本名称引用资产(没有目录,没有路径的扩展部分),您还可以使用完整的相对路径(包括文件扩展名,相对于项目根目录)。

我们说我已经从目录Assets/Bundle创建了包,它包含以下文件:

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

因此,在我们的案例中加载预制件的文件记录方式是

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

这是在我们的案例中正确运作的未记录的方式

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

如果您不确定LoadAsset应使用的正确资产名称是什么,可以使用以下代码列出bundle

中的所有资产名称
string[] assets = bundle.GetAllAssetNames();
foreach (string asset in assets)
{
    Debug.Log(asset);
}