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;
    }
}

  

posted @ 2020-12-13 18:03  丝袜骑士  阅读(122)  评论(0编辑  收藏  举报