在进行打包时在打包目录下会生成一个文件,在LuaFrameWork里面这个文件的名字一般是叫“StreamingAsset”,我这里命名为My_AssetBundle
AppConst.GetSAurl() 为打包目录的路径: xxx…/My_AssetBundle
AppConst.ExtName = “.unity3d”; //为后缀名
在游戏启动时,一般需要先加载My_AssetBundle这个文件,把里面的bundle名以及依赖用字典存起来
Dictionary<string, List<string>> m_manifest = new Dictionary<string, List<string>>();
/// <summary>
/// 加载打包之后生成的My_AssetBundle文件自己(不带后缀名的那个文件),
/// </summary>
/// <returns></returns>
IEnumerator LoadStreamingAsset()
{
AssetBundle assetBundle = AssetBundle.LoadFromFile(AppConst.GetSAurl() + "/My_AssetBundle");
AssetBundleManifest allManifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
yield return allManifest;
readManifest(allManifest);
}
public void readManifest(AssetBundleManifest manifest)
{
for (int i = 0; i < manifest.GetAllAssetBundles().Length; i++)
{
string abName = manifest.GetAllAssetBundles()[i];
List<string> dpArr = new List<string>(manifest.GetAllDependencies(abName));
m_manifest.Add(abName, dpArr);
}
Debug.Log("is LoadStreamingAsset Finish");
}
加载一张sprite示例
public class LoadSpriteFile : MonoBehaviour
{
Image img;
Image img_2;
// Start is called before the first frame update
void Start()
{
img = transform.Find("icon").GetComponent<Image>();
img_2 = transform.Find("icon_2").GetComponent<Image>();
string spName = "Icon/test11.png";
StartCoroutine(LoadSp(spName, AppConst.spriteDirName));
}
IEnumerator LoadSp(string spName, string IconPath)
{
string[] s = spName.Split('/');
string bundleParName = s[0].ToLower();
string resPath = AppConst.GetSAurl() + "/" + IconPath + "/" + bundleParName + AppConst.ExtName;
Debug.Log("resPath ="+resPath);
WWW www = new WWW(resPath);
AssetBundleCreateRequest abcrequest = null;
yield return www;
if (www.error != null)
{
Debug.LogError("www Error, msg =" + www.error);
www.Dispose();
www = null;
}
else
{
abcrequest = AssetBundle.LoadFromMemoryAsync(www.bytes);
www.Dispose();
www = null;
}
yield return abcrequest;
AssetBundle assetBundle = abcrequest.assetBundle;
string spriteName = s[s.Length - 1];
Sprite sp1 = assetBundle.LoadAsset<Sprite>(spriteName);
yield return sp1;
img.sprite = sp1;
//异步加载方式 后面需要传一个类型进去
AssetBundleRequest request = assetBundle.LoadAssetAsync(spriteName,typeof(Sprite));
yield return request;
Debug.Log("request =" + request.asset.name);
Sprite sp2 = request.asset as Sprite;
img_2.sprite = sp2;
}
}
这是加载sprite,sprite为独立的资源,这些资源不含依赖,所以加载比较简单,那如果需要加载一个预设
每个预设一般都含有依赖,在打包的时候就应该注意把预设的所有依赖项都打进包里,以免造成在游戏中资源丢失的情况。那需要重新写一个通用的加载方法:
IEnumerator LoadMyAsset<T>(string bundlePath, string assetName, Action<UnityEngine.Object> func = null) where T : UnityEngine.Object
{
bundlePath = bundlePath.ToLower();
string[] s = bundlePath.ToLower().Split('/');
string resPath = AppConst.GetSAurl() + "/" + bundlePath;
Debug.Log("resPath =" + resPath);
WWW www = new WWW(resPath);
AssetBundleCreateRequest abcrequest = null;
yield return www;
if (www.error != null)
{
Debug.LogError("www Error, msg =" + www.error);
www.Dispose();
www = null;
}
else
{
abcrequest = AssetBundle.LoadFromMemoryAsync(www.bytes);
www.Dispose();
www = null;
}
yield return abcrequest;
AssetBundle assetBundle = abcrequest.assetBundle;
AssetBundleRequest request = assetBundle.LoadAssetAsync(assetName.ToLower(), typeof(T));
yield return request; //request:加载到这里就代表这一个bundle加载完毕
//Debug.Log("reqAssname =" + request.asset.name);
func?.Invoke(request.asset); //回调方法
}
加载一个预设
加载一个预设需要先把预设的所有依赖加载出来,再来加载预设自己,不然会出现加载出来的预设中的贴图或者其他丢失的情况,这里都采用异步加载
AppConst.prefabDirName = “ui” //这个就是你打包出来的预设所存放的目录
IEnumerator startCo()
{
yield return StartCoroutine(LoadStreamingAsset());
//string preName = "MyAssPrefab";
string preName = "MyAssPrefab_small";
yield return StartCoroutine(LoadPref(preName, AppConst.prefabDirName));
}
/// <summary>
/// 加载一个预设
/// </summary>
/// <param name="preName"> 预设名字 </param>
/// <param name="PrefPath"> 打出的预设包存放的文件夹名字 </param>
/// <returns></returns>
IEnumerator LoadPref(string preName, string PrefPath)
{
List<string> dependencies = null;
string key = AppConst.prefabDirName + "/" + preName.ToLower() + AppConst.ExtName;
//Debug.Log("preKey ="+ key);
if (m_manifest.TryGetValue(key, out dependencies))
{
//先加载依赖
for (int i = 0; i < dependencies.Count; i++)
{
string[] s = dependencies[i].Split('/');
if (m_manifest.ContainsKey(dependencies[i]) && (s[0].StartsWith("sprite") || s[0].StartsWith("texture")))
{
Debug.Log("***dp" + i + ":" + dependencies[i]);
//转到加载依赖的协程
yield return StartCoroutine(LoadMyAsset<Sprite>(dependencies[i], s[s.Length - 1]));
}
}
}
string resPath = AppConst.GetSAurl() + "/" + PrefPath + "/" + preName.ToLower() + AppConst.ExtName;
WWW www = new WWW(resPath);
Debug.Log("resPath =" + resPath);
yield return www;
AssetBundleCreateRequest abcrequest = null;
if (www.error != null)
{
www.Dispose();
Debug.LogError("www Err,Msg =" + www.error);
www = null;
}
else
{
abcrequest = AssetBundle.LoadFromMemoryAsync(www.bytes);
www.Dispose();
www = null;
}
yield return abcrequest;
AssetBundle assetBundle = abcrequest.assetBundle;
AssetBundleRequest request = assetBundle.LoadAssetAsync(preName, typeof(GameObject));
yield return request;
// 预设加载完成,实例化这个预设看看效果
Debug.Log("request =" + request.asset.name);
GameObject InsGameObj = GameObject.Instantiate(request.asset as GameObject);
InsGameObj.transform.name = "newObj";
InsGameObj.transform.SetParent(Canvas);//Canvas : 某个父物体,能在场景中显示就行
InsGameObj.transform.localPosition = Vector3.one;
}
运行起来就能在场景中看到你刚刚加载的预设。这就是加载一个预设的过程
一定要注意是需要先加载依赖。
其他资源加载其实都大同小异,可以自己去摸索一下,这边不赘述,关于AssetBundle打包的可以去我的其他博客看一下,传送门:AssetBundle打包