Unity版本:Unity 5.6.6f2
基本流程
- 同步或异步方式读取assetbundle本地文件
- clone一个gameobject
// LocalFileMgr.cs
using System.IO;
using UnityEngine;
public class LocalFileMgr
{
#region 单例
private static LocalFileMgr instance;
public static LocalFileMgr Instance
{
get
{
if(instance == null )
{
instance = new LocalFileMgr();
}
return instance;
}
}
#endregion
#if UNITY_EDITOR
#if UNITY_STANDALONE
public readonly string LocalFilePath = Application.dataPath + "/../AssetBundles/Windows/";
#elif UNITY_IPHONE
public readonly string LocalFilePath = Application.dataPath + "/../AssetBundles/iOS/";
#elif UNITY_ANDROID
public readonly string LocalFilePath = Application.dataPath + "/../AssetBundles/Android/";
#endif
#elif UNITY_STANDALONE || UNITY_IPHONE || UNITY_ANDROID
public readonly string LocalFilePath = Application.persistentDataPath + "/";
#endif
/// <summary>
/// 加载本地资源文件 保存到byte数组
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public byte[] LoadByteArrayFromLocalFile(string path)
{
byte[] buffer = null;
using (FileStream fs = new FileStream(path, FileMode.Open))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
}
return buffer;
}
}
同步读取操作
// AssetBundleLoaderSync.cs
using System;
using UnityEngine;
public class AssetBundleLoaderSync : IDisposable
{
private AssetBundle bundle;
public AssetBundleLoaderSync(string assetsPath)
{
string fullPath = LocalFileMgr.Instance.LocalFilePath + assetsPath;
bundle = AssetBundle.LoadFromMemory(LocalFileMgr.Instance.LoadByteArrayFromLocalFile(fullPath));
}
public T LoadAsset<T> (string name) where T : UnityEngine.Object
{
if (bundle == null) return default(T);
return bundle.LoadAsset(name) as T;
}
public void Dispose()
{
if (bundle != null) bundle.Unload(false);
}
}
异步读取操作
// AssetBundleLoaderAsync.cs
using System.Collections;
using UnityEngine;
public class AssetBundleLoaderAsync: MonoBehaviour
{
private string m_FullPath;
private string m_Name;
AssetBundleCreateRequest abRequest = new AssetBundleCreateRequest();
AssetBundle bundle = new AssetBundle();
public System.Action<UnityEngine.Object> OnLoadComplete;
public void Init(string assetPath, string assetName)
{
m_FullPath = LocalFileMgr.Instance.LocalFilePath + assetPath;
m_Name = assetName;
}
void Start()
{
StartCoroutine(Load());
}
private IEnumerator Load()
{
abRequest = AssetBundle.LoadFromMemoryAsync(LocalFileMgr.Instance.LoadByteArrayFromLocalFile(m_FullPath));
yield return abRequest;
bundle = abRequest.assetBundle;
if (OnLoadComplete != null)
{
OnLoadComplete(bundle.LoadAsset(m_Name));
Destroy(this.gameObject);
}
}
void OnDestroy()
{
if (bundle != null) bundle.Unload(false);
m_FullPath = null;
m_Name = null;
}
}
管理类提供两种读取方式的入口
// AssetBundleMgr.cs
using UnityEngine;
public class AssetBundleMgr
{
#region 单例
private static AssetBundleMgr instance;
public static AssetBundleMgr Instance
{
get
{
if(instance == null )
{
instance = new AssetBundleMgr();
}
return instance;
}
}
#endregion
public GameObject Load(string assetPath, string assetName)
{
using (AssetBundleLoaderSync loader = new AssetBundleLoaderSync(assetPath))
{
if (loader != null)
{
GameObject go = loader.LoadAsset<GameObject>(assetName);
if (go != null)
return go;
}
return null;
}
}
public GameObject LoadClone(string assetPath, string assetName)
{
using (AssetBundleLoaderSync loader = new AssetBundleLoaderSync(assetPath))
{
if (loader != null)
{
GameObject go = loader.LoadAsset<GameObject>(assetName);
if(go != null)
return GameObject.Instantiate(go);
}
return null;
}
}
public AssetBundleLoaderAsync LoadAsync(string assetPath, string assetName)
{
GameObject go = new GameObject("AssetBundleLoaderAsync");
AssetBundleLoaderAsync abAsync = go.GetOrCreateGO<AssetBundleLoaderAsync>();
abAsync.Init(assetPath, assetName);
return abAsync;
}
}
测试类中调用:
// Test.cs
using UnityEngine;
public class Test : MonoBehaviour
{
void Start()
{
AssetBundleMgr.Instance.LoadClone(@"Role\maincity_role_cike.assetbundle", "MainCity_Role_Cike");
// 异步调用需要在回调函数中实现clone
AssetBundleMgr.Instance.LoadAsync(@"Role\maincity_role_cike.assetbundle", "MainCity_Role_Cike").OnLoadComplete = (Object go) => {
Instantiate(go);
};
}
}
期间可能会遇到材质球丢失的问题,这是因为Unity的配置只有默认几个shader,而如果没有把自定义的shader配置上,打包后就会丢失shader,配置方法如下:
Edit -> Project Setting -> Graphics
红框内是我自己用到的一个shader,加入后重新打包再加载即可。