找回密码
 立即注册
查看: 267|回复: 0

Unity面试问题学习笔记(6)——AB包资源管理器

[复制链接]
发表于 2022-9-26 16:15 | 显示全部楼层 |阅读模式
1.单例基类模块:

作用:减少单例模式重复代码的书写
知识点:

  • C#的泛型<T>与继承,class 类名<T>(父类) ||  class 类型 : 父类名<T>(子类)
  • C#的约束(where),约束指定类型参数的功能和预期。 声明这些约束意味着你可以使用约束类型的操作和方法调用。 如果泛型类或方法对泛型成员使用除简单赋值之外的任何操作或调用 System.Object 不支持的任何方法,则必须对类型参数应用约束。 例如,基类约束告诉编译器,仅此类型的对象或派生自此类型的对象可用作类型参数。 编译器有了此保证后,就能够允许在泛型类中调用该类型的方法。 where T :Component
  • 单例模式,private static 类名 instance,还需要有一个public static GetInstance()方法来获取这个单例对象。简单来说就是整个游戏中只有一个的对象,例如资源管理器等,可以使用单例,方便其他类直接调用。
  • 里式转换原则,派生类(子类)对象可以在程式中代替其基类(超类)对象,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定子类类型,用子类对象来替换父类对象。(基类定义,子类运行)。
  • 多态,将基类的Awake写成虚函数,在派生类中重写Awake函数并调用base.Awake();来实例化自己(这种方法需要自己保证只能挂载一个单例脚本)
  • Auto版本,在基类的GetInstance中新建一个专门的GameObject来存放这个单例脚本,从而保证唯一性,并允许派生类写自己的Awake函数。
2.ABManager(同步加载):

概念:ABManager用于实现AB包和资源的加载。
重要字段和属性:

  • 字段和属性的参考文献:


  • 主包,Manifest,AB包字典,路径:
   //主包
    private AssetBundle mainAB = null;
    //依赖包Manifest
    private AssetBundleManifest mainManifest = null;
    //AB包不能重复加载 否则会报错
    //字典 用字典来存储 加载过的AB包
    private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();
    //AB包存放路径
    private string pathURL
    {
        get
        {
            return Application.streamingAssetsPath + "/";
        }
    }
    //主包名,方便修改
    private string mainABName
    {
        get
        {
            return "PC";
        }
    }
AB包加载:
public void LoadAB(string abName)
    {
        //获取依赖包相关信息
        //加载主包
        if (mainAB == null)
        {
            mainAB = AssetBundle.LoadFromFile(pathURL + mainABName);
        }
        //加载主包的Manifest
        if (mainManifest == null)
        {
            mainManifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        }
        //加载依赖包
        string[] strs = mainManifest.GetAllDependencies(abName);
        AssetBundle ab = null;
        foreach (string dStr in strs)
        {
            if (!abDic.ContainsKey(dStr))
            {
                ab = AssetBundle.LoadFromFile(pathURL + dStr);
                abDic.Add(dStr, ab);
            }
        }
        //加载目标包
        if (!abDic.ContainsKey(abName))
        {
            ab = AssetBundle.LoadFromFile(pathURL + abName);
            abDic.Add(abName, ab);
        }
    }
资源加载(三种方式):

  • 只是用名字加载,方法返回Object类型,在外面调用方法时需要强制转换返回值为需要的类型。
  • 名字和Type加载,方法返回Object类型,可以选择指定类型的资源进行返回。和第一种方法一样,需要强制转换。最Lua中运用最方便。
  • 泛型加载,防范返回T(泛型)类型,不需要强制转换,在C#中运用最方便。
资源卸载:

  • 单个包卸载,注意卸载完要删除字典中对应的键值对。
    public void UnLoad(string abName)
    {
        if (abDic.ContainsKey(abName))
        {
            abDic[abName].Unload(false);
            abDic.Remove(abName);
        }
    }

  • 全部包卸载,注意置空所有的字段和属性(字典,主包,Manifest文件)
public void ClearAB()
    {
        AssetBundle.UnloadAllAssetBundles(false);
        abDic.Clear();
        mainAB = null;
        mainManifest = null;
    }
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 10:48 , Processed in 0.091799 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表