1

我对统一的资产包有疑问。我有一个包含多个资产的捆绑包,名称相同,但扩展名不同,例如 bonus.png bonus.prefab。

当我尝试实例化一个名为 Bonus 的预制件时,assetBundle.LoadAssets("bonus") 函数不会像通常那样返回一个游戏对象。这似乎只有在我有多个同名资产时才会发生。

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 循环,我可以找到我的资产并正确地实例化它。但这只是一种肮脏的做法。

4

3 回答 3

1

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

您使用的是哪个版本的 Unity?

您上面的代码看起来是正确的(除了称为 LoadAssetAsync 的拼写错误?),我们不确定它是否无法输入 if() 语句?

以下在 Unity 4.5.5f1 上为我工作

  1. 从Unity Docs向我的 Unity 构建添加了 ExportAssetBundles.cs 上下文菜单脚本

  2. 创建了要导出的东西

    • 找到一张JPG拖进去,命名为“marble.jpg”
    • 创建了一个立方体,将其命名为“大理石”并将其拖到项目中以创建一个预制件
    • 创建一个材质,命名为“大理石”,添加 jpg 并将其拖到立方体上,按下应用。
  3. 使用“从选择构建资产 - 轨道选择”突出显示所有 3 个和导出的资产包并将其保存到“c:\temp\marble.unity3d”

  4. 添加了一个脚本以在启动时加载该资产包(与您的类似):

    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. 运行 Unity 并验证我正确地看到了游戏对象。

于 2014-12-17T13:13:32.353 回答
1

它曾经在我使用 unity 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));
        }
    }

它正在工作,但我真的不喜欢这种方式。

于 2014-12-17T13:43:12.307 回答
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);
}
于 2015-08-01T09:39:07.303 回答