您的位置:首页 > 移动开发 > Unity3D

unity AssetBudle 的引用计数(资源优化)

2020-02-02 11:53 1321 查看

 首先写一个类包含ab和ab对应的引用以及对应的卸载方法,在写一个ab的管理类,包括全局ab的加载,卸载,以及相关根据引用数来判断是重内存中是否删除对应的依赖资源,是新建资源还是重内存中获取资源重而达到在ab适度颗粒话下的内存优化!

脚本:

[code]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

}

 

  • 点赞
  • 收藏
  • 分享
  • 文章举报
东皇十三妖 发布了12 篇原创文章 · 获赞 0 · 访问量 921 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: