zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    

      

  • 相关阅读:
    POJ 1001 Exponentiation
    POJ 2105 IP Address
    条款1:视C++为一个语言联邦
    条款2:尽量使用const ,enum,inline替换define
    走台阶问题
    Oracle之分页问题
    Oracle之子查询:Top-N问题
    Facade——外观模式
    PROXY——代理模式
    C++ 内联函数
  • 原文地址:https://www.cnblogs.com/space1996/p/14118319.html
Copyright © 2011-2022 走看看