UF_OLDL4——公共Mono模块

公共Mono模块

Unity协程和Update()帧更新等只有在继承MonoBehaviour的类里才能使用,
但我们有不少类是不继承MonoBehaviour的,那我们应该如何让它们能够使用Update()和开启协程呢?

使用公共Mono模块,来让不继承MonoBehaviour的类来使用上一些MonoBehaviour的内容,
例如开启协程,可以Update更新,并统一管理Update()

知识点:生命周期函数,事件,协同程序

对外开放部分——公共Mono模块管理者

单例公共Mono模块的管理者,封装一个唯一的Mono模块控制者用于对外开放和统一管理
可以给外部添加帧更新事件方法,也可以通过该模块为非继承MonoBehavior的类开启协程

封装了一个唯一的公共MonoBehaviour模块控制者
对外实现了帧更新和开启协程的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
using System.Collections;
using System.ComponentModel;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 单例公共Mono模块的管理者,封装一个唯一的Mono模块控制者用于统一管理,可以给外部添加帧更新事件方法
/// 也可以通过该模块为非继承MonoBehavior的类开启协程
/// </summary>
public class MonoManager : BaseManager<MonoManager>
{
private MonoController controller;

/// <summary>
/// 在第一次调用该模块时,会进入该构造方法在场景上创建空对象,并把Mono模块控制器挂载在某个对象上
/// </summary>
public MonoManager()
{
//保证了MonoControllor对象的唯一性,使该管理器私有变量一定装载的是这里构造函数实例化的Mono控制器
GameObject obj = new GameObject("MonoController");
controller = obj.AddComponent<MonoController>();
}

/// <summary>
/// 提供给外部的添加Update()帧更新事件的函数,注意要配套使用移除方法,至少要在对象被销毁前使用移除方法以避免内存泄露
/// </summary>
/// <param name="func">要帧更新的方法</param>
public void AddUpdateListener(UnityAction func)
{
controller.AddUpdateListener(func);
}

/// <summary>
/// 提供给外部的移除Update()帧更新事件的函数
/// </summary>
/// <param name="func">要移除的方法</param>
public void RemoveUpdateListener(UnityAction func)
{
controller.RemoveUpdateListener(func);
}

/// <summary>
/// 提供给外部开启协程的方法
/// </summary>
/// <param name="routine">协程所用的迭代器函数</param>
/// <returns>在Mono模块开启的协程</returns>
public Coroutine StartCoroutine(IEnumerator routine)
{
return controller.StartCoroutine(routine);
}

public Coroutine StartCoroutine(string routine, [DefaultValue("null")] object value)
{
return controller.StartCoroutine(routine, value);
}

/// <summary>
/// Controller内部函数开启协程的方法,只适用于开启Controller内的函数,外部不能使用
/// </summary>
/// <param name="methodName">函数名</param>
/// <returns>开启的协程</returns>
public Coroutine StartCoroutine(string methodName)
{
return controller.StartCoroutine(methodName);
}
}

底层实际执行部分——公共Mono模块控制者

公共Mono模块控制者,是实际继承MonoBehaviour的类,需要依附一个对象,过场景不销毁
不是单例,不单独使用,一般被单例管理者封装管理,通过管理者获取要执行的帧更新函数和用于开启协程的迭代器函数
传入管理者的帧更新函数和迭代器函数,都实际在这个类里下执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// 公共Mono模块控制者,实际继承MonoBehaviour的类,不是单例,不单独使用,一般被单例管理者封装管理
/// </summary>
public class MonoController : MonoBehaviour
{
public event UnityAction updateEvent;

// Start is called before the first frame update
void Start()
{
//过场景时,要确保该公共Mono控制者模块不会被移除
DontDestroyOnLoad(this.gameObject);
}

// Update is called once per frame
void Update()
{
if (updateEvent != null)
updateEvent.Invoke();
}

/// <summary>
/// 提供给外部的添加Update()帧更新事件的函数,注意要配套使用移除方法,至少要在对象被销毁前使用移除方法以避免内存泄露
/// </summary>
/// <param name="func">要帧更新的方法</param>
public void AddUpdateListener(UnityAction func)
{
updateEvent += func;
}

/// <summary>
/// 提供给外部的移除Update()帧更新事件的函数
/// </summary>
/// <param name="func">要移除的方法</param>
public void RemoveUpdateListener(UnityAction func)
{
updateEvent -= func;
}
}