U3D资源加载框架迭代笔记
V0.0.1
一个初始的资源加载,卸载功能,list记录加载过的资源,这里只用Resources类作为演示,不用AB包加载。
using System.Collections.Generic;
using UnityEngine;
public class ResLoader
{
//资源加载记录
private List<UnityEngine.Object> mLoadedAssets = new List<UnityEngine.Object>();
//加载资源
public T LoadAsset<T>(string assetName,string path) where T : Object
{
var asset = mLoadedAssets.Find(loadedAsset => loadedAsset.name == assetName)as T;
if (asset != null)
{
return asset;
}
asset = Resources.Load<T>(path + "/" + assetName);
mLoadedAssets.Add(asset);
return asset;
}
//卸载资源
public void UnLoadAllAssets()
{
foreach (Object loadedAsset in mLoadedAssets)
{
Resources.UnloadAsset(loadedAsset);
}
mLoadedAssets.Clear();
mLoadedAssets = null;
}
}
V0.0.2
1.将资源封装到Res类中
2.Res类添加引用计数功能,统计资源被引用的次数
3.设计引用计数模块
4.ResLoader代码重构,加入可全局访问的“资源加载记录池”
引用计数模块设计:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//引用计数
public interface IRefCounter
{
int RefCount { get; }
void Retain(object refOwner = null);
void Release(object refOwner = null);
}
public class RcBase : IRefCounter
{
public RcBase()
{
RefCount = 0;
}
public int RefCount
{
get;
private set;
}
public void Release(object refOwner = null)
{
RefCount--;
if (RefCount == 0)
{
OnZeroRef();
}
}
public void Retain(object refOwner = null)
{
RefCount++;
}
protected virtual void OnZeroRef() { }
}
对资源进行封装:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//对 asset进行封装,并添加引用计数功能
public class Res :RcBase
{
public Object Asset { get; private set; }
public string Name
{
get
{
return Asset.name;
}
}
//初始化构造方法
public Res(Object asset)
{
Asset = asset;
}
protected override void OnZeroRef()
{
base.OnZeroRef();
//卸载资源
Resources.UnloadAsset(Asset);
ResLoader.sharedLoadedRes.Remove(this);
}
}
ResLoader代码重构:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ResLoader
{
//所有ResLoader对象的加载记录池
public static List<Res> sharedLoadedRes = new List<Res>();
//该对象的加载资源记录
private List<Res> mResRecord = new List<Res>();
public T LoadAsset<T>(string assetName,string path) where T : Object
{
//如果该对象已经加载了资源
var res = mResRecord.Find(loadedAsset => loadedAsset.Name == assetName);
if (res != null)
{
return res.Asset as T;
}
//如果全局缓存了资源
res = sharedLoadedRes.Find(loadedAsset => loadedAsset.Name == assetName);
if (res != null)
{
res.Retain();
return res.Asset as T;
}
//如果没有缓存资源,从Resources文件夹里加载
var asset = Resources.Load<T>(path + "/" + assetName);
res = new Res(asset);
res.Retain();
//将加载后的资源记录到池中
mResRecord.Add(res);
sharedLoadedRes.Add(res);
return res.Asset as T;
}
//只卸载该ResLoader对象加载过的资源,其他ResLoader对象加载的资源不卸载
public void UnLoadAllAssets()
{
foreach (Res loadedAsset in mResRecord)
{
Resources.UnloadAsset(loadedAsset.Asset);
}
mResRecord.Clear();
mResRecord = null;
}
}

浙公网安备 33010602011771号