IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity管理器驱动怎么做?简单聊下静态类与解耦 -> 正文阅读

[游戏开发]Unity管理器驱动怎么做?简单聊下静态类与解耦

????????在前边的文章里提到了,我们希望做一个拦截Unity?Log的管理类,并且初衷是希望,程序直接把这个脚本拖动到工程里,别的什么代码都不用动,管理类就能自动运行。然而当时测试的结果并不行。

? ? ? ? 我们问题的关键点在于,不改动其它的代码。试想一下,如果一个类不被别的类初始化和调用,那它的代码怎么执行?所以我最开始的想法是把初始化直接放到类的静态构造函数里去。但是这样做并没有用。

? ? ? ? 因为类的静态构造函数的执行时机是不确定的,它只能保证类在被引用前一定会执行完静态构造函数,我们看一下官方怎么说的

A static constructor is called automatically. It initializes the?class?before the first instance is created or any static members are referenced. A static constructor runs before an instance constructor. A type's static constructor is called when a static method assigned to an event or a delegate is invoked and not when it is assigned. If static field variable initializers are present in the class of the static constructor, they're executed in the textual order in which they appear in the class declaration. The initializers run immediately prior to the execution of the static constructor.

? ? ? ? 所以如果一个静态类不被外部引用,它的静态构造函数就不会执行。所以这种外挂式的方法就行不通了。而我们项目里也没有提供这种独立挂载的机制,所以不得不在启动类里手动调用一下新写的类了。

? ? ? ? 那么有什么方法可以方便做到“解耦”呢?那基本上是要用到反射,我们知道我们自己写的代码都是在一个程序集里的,但这也意味着,这种设计最开始就要在整个系统的架构中才行。

? ? ? ? 我们先定义一个管理器接口

public interface IGameManager
{
    void Init();
    void Update(float deltaTime);
}

? ? ? ? 我们希望做到的是,所有继承自这个接口的类,都会在游戏初始化时自动调用该类的初始化,在游戏帧循环时自动调用该类的帧循环。

? ? ? ? 然后我们定义一个测试用的管理类LogManager

public class LogManager : IGameManager
{
    public void Init()
    {
        Debug.Log("Log Manager Init");
    }

    public void Update(float deltaTime)
    {
        Debug.Log("Log Manager Update");
    }
}

? ? ? ? 代码非常简单,就是打印一下。接下来我们在场景里挂一个启动的脚本作为测试,我们解耦的思路是什么呢,就是在游戏管理器初始化的时候,通过反射获取到程序集里的所有类型,然后判断哪些类型是继承自IGameManager的,找到所有这样的类,通过反射创建实例化对象,并调用管理器的接口。??

public class ManagerLauncher : MonoBehaviour
{
    private List<IGameManager> _managers;
    void Start()
    {
         _managers = new List<IGameManager>();
        Type[] types = typeof(ManagerLauncher).Assembly.GetTypes();
        foreach (var type in types)
        {
            if (type.GetInterface("IGameManager") != null)
            {
                var manager = Activator.CreateInstance(type) as IGameManager;
                manager.Init();
                _managers.Add(manager);
            }
        }
    }
    
    void Update()
    {
        foreach (var manager in _managers)
        {
            manager.Update(Time.deltaTime);
        }
    }
}

????????代码非常的简单清晰,足够说明问题了,就不再注释和解释了。

????????运行游戏,代码如预期执行了

????????这样就达到了解耦的目的,后续需要添加新的管理器,就不需要改动其它的代码,只要新的管理器继承自这个接口。就会被自动驱动。

? ? ? ? 这是一种解耦的思路,其缺点是不够灵活和定制化。比如我们有两个管理器A和B,A有两个初始化方法,其中一个初始化要在B初始化之前执行,另一个要在B初始化之后执行。如果按照传统的做法,可以这么写

void GameInit()
{
    A.Init_Before_B();
    B.Init();
    A.Init_After_B();
}

? ? ? ? 但是用自动初始化就需要一些额外的工作,不是不能做。比如给接口增加一个Priority的优先级属性,在通过反射获取到所有类以后,先排序,然后再初始化。对于上边那个接口,甚至可以在A的初始化里初始化B,然后调用A的剩余部分,B的初始化不执行任何功能。但总体来说还是应该尽量避免这样的设计,如果有顺序依赖,也应该把顺序更清晰一些,减少这种交叉的存在,优先考虑类的布局,而不是依赖强大的管理器驱动程序。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-28 09:41:08  更:2021-08-28 09:41:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/2 20:11:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码