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

      

  • 相关阅读:
    vim 高级使用技巧第二篇
    你所不知道的Html5那些事(一)
    linux设备驱动第三篇:如何实现一个简单的字符设备驱动
    Android Metro风格的Launcher开发系列第二篇
    「BZOJ3123」[SDOI2013]森林
    【模板】左偏树
    「luogu3157」[CQOI2011]动态逆序对
    「luogu3567」[POI2014]KUR-Couriers
    【模板】二逼平衡树
    「luogu3313」[SDOI2014]旅行
  • 原文地址:https://www.cnblogs.com/space1996/p/14118319.html
Copyright © 2020-2023  润新知