首先寫一個類包含ab和ab對應的引用以及對應的解除安裝方法,在寫一個ab的管理類,包括全局ab的加載,解除安裝,以及相關根據引用數來判斷是重記憶體中是否删除對應的依賴資源,是建立資源還是重記憶體中擷取資源重而達到在ab适度顆粒話下的記憶體優化!
腳本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class AssetBundleInfos
{
public AssetBundle assetBundle;
public int referencedCount;//引用數
internal event Action unload;
internal void OnUnload()
{
assetBundle.Unload(false);
if (unload != null)
unload();
}
}
public class Resource_LoadManager
{
AssetBundleManifest assetBundleManifest = null;
Dictionary<string, string[]> dependencies = new Dictionary<string, string[]>();
Dictionary<string, AssetBundleInfos> loadeAssetBundle = new Dictionary<string, AssetBundleInfos>();
// Use this for initialization
public Resource_LoadManager()
{
//Initalize();
}
//初始化加載所有的依賴項目
public void Initalize()
{
AssetBundle bundle;
switch (Application.platform)
{
case RuntimePlatform.Android:
bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Android"));
break;
case RuntimePlatform.IPhonePlayer:
bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Ios"));
break;
case RuntimePlatform.WindowsEditor:
bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Android"));
break;
case RuntimePlatform.OSXEditor:
bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "Ios"));
break;
default:
bundle = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, "StandaloneWindows"));
break;
}
assetBundleManifest = bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
// 壓縮包釋放掉
bundle.Unload(false);
bundle = null;
// depengcies = manifest.GetDirectDependencies("cube.assetbundle");
//加載所有的依賴項
}
public static string DataPath
{
get
{
string game = "Framework";//AppConst.AppName.ToLower();
if (Application.isMobilePlatform)
{
return Application.persistentDataPath + "/" + game + "/";
}
if (Application.platform == RuntimePlatform.OSXEditor)//mac平台
{
int i = Application.dataPath.LastIndexOf('/');
return Application.dataPath.Substring(0, i + 1) + game + "/";
}
//return Application.dataPath + "/" + "StreamingAssets" + "/";
return "d:/" + game + "/";//window本地位址
}
}
//加載assetBundle的操作
public AssetBundle Load_assetBundle(string abName)
{
if (abName.Contains("\\"))
abName = abName.Replace("\\", "/");
if (abName.Contains("/."))
abName = abName.Replace("/.", ".");
AssetBundleInfos ab = Get_AssetBundle(abName);
if (ab == null)
{
//新增加的ab處理
AssetBundle abNew = AssetBundle.LoadFromFile(System.IO.Path.Combine(DataPath, abName));
if (abNew == null)
{
Debug.LogError(abName + " isnot exist file of in" + DataPath);
return null;
}
AssetBundleInfos newAssetInfo = new AssetBundleInfos();
newAssetInfo.assetBundle = abNew;
newAssetInfo.referencedCount++;
loadeAssetBundle.Add(abNew.name, newAssetInfo);
//擷取加載的ab 對應的依賴
string[] denpengcess = assetBundleManifest.GetDirectDependencies(abName);
for (int i = 0; i < denpengcess.Length; i++)
{
string depName = denpengcess[i];
AssetBundleInfos bundleInfo = null;
//給對應的依賴資源增加引用數
if (loadeAssetBundle.TryGetValue(depName, out bundleInfo))
{
bundleInfo.referencedCount++;
}
else
{
Load_assetBundle(depName);
}
}
dependencies.Add(abName, assetBundleManifest.GetDirectDependencies(abName));
return abNew;
}
else
{
ab.referencedCount++;
return ab.assetBundle;
}
}
//從集合中查找對象是否已經被加載
AssetBundleInfos Get_AssetBundle(string abName)
{
AssetBundleInfos abInfo = null;
if (!loadeAssetBundle.TryGetValue(abName, out abInfo))
{
return null;
}
return abInfo;
}
#region 解除安裝
/// <summary>
/// Unloads assetbundle and its dependencies.
/// </summary>
public void UnloadAssetBundle(string assetBundleName)
{
UnloadAssetBundleInternal(assetBundleName);
}
protected void UnloadDependencies(string assetBundleName)
{
string[] dependenciesNes = null;
if (!dependencies.TryGetValue(assetBundleName, out dependenciesNes))
return;
// Loop dependencies.
foreach (var dependency in dependenciesNes)
{
UnloadAssetBundle(dependency);
}
dependencies.Remove(assetBundleName);
}
protected void UnloadAssetBundleInternal(string assetBundleName)
{
//string error;
AssetBundleInfos bundle = Get_AssetBundle(assetBundleName);
if (bundle == null)
return;
//計數減少 後對應的資源沒有引用了處理
if (--bundle.referencedCount <= 0)
{
//對依賴資源的依賴處理
UnloadDependencies(assetBundleName);
bundle.OnUnload();
//移除緩存
loadeAssetBundle.Remove(assetBundleName);
}
else
{
--bundle.referencedCount;
}
}
#endregion
#region 加載
#endregion
}