Unity游戏框架学习笔记——04公共MONO模块
公共MONO模块
一如既往指路牌:https://www.bilibili.com/video/BV1C441117wU?p=6.
视频原本是免费的,完整视频移步泰课吧/(ㄒoㄒ)/~~…
泰课指路牌:https://www.taikr.com/course/1062/task/31006/show.
这个模块是用于给没有继承MonoBehavior的类可以执行帧更新函数Update(),统一管理Update,并且可以开启协程方法。
实现
① 没继承MonoBehavior也可以执行Update()
创建一个MonoController脚本,在类中声明一个私有的事件类型的成员变量,这个脚本的Update()中执行这个事件委托对象,并且给外部提供添加执行帧更新函数、移除执行帧更新函数的方法。
那么当脚本MonoController的Update()执行的时候,就相当于把要执行帧更新的函数一并执行,就是实现了让没继承MonoBehavior的函数也可以在帧更新中被调用。
代码
/// <summary>
/// Mono的管理器
/// </summary>
public class MonoController : MonoBehaviour
{
private event UnityAction UpdateEvent;
// Start is called before the first frame update
void Start()
{
// 不让该对象被移除
DontDestroyOnLoad(this.gameObject);
}
// Update is called once per frame
void Update()
{
if (UpdateEvent != null)
{
UpdateEvent();
}
}
/// <summary>
/// 提供给外部 添加需要实现帧更新的函数
/// </summary>
/// <param name="func"></param>
public void AddUpdateListener(UnityAction func)
{
UpdateEvent += func;
}
/// <summary>
/// t提供给外部 移除不执行帧更新的函数
/// </summary>
/// <param name="func"></param>
public void RemeveUpdateListerner(UnityAction func)
{
UpdateEvent -= func;
}
}
② 统一管理Update
为什么会有这个功能就是因为没有继承MonoBehavior的类的函数如果要实现帧更新,就需要在脚本里面找到场景中挂载这个Mono管理器的对象,获取这个对象的MonoController脚本,然后再获取对应的方法,其实是有点麻烦的。
那么如果我们将它封装在静态类里面呢?
就可以省去获取对象->获取对象上MonoController脚本,这一步了,我们可以直接通过静态类来访问其中的添加和移除帧更新的方法,而这个静态类就相当于是为外部提供一个访问的渠道,它本身的功能即是用于统一管理MonoController中的需要Update()的方法。
代码
/// <summary>
/// Mono管理器的封装
/// </summary>
public class MonoManeger : Singleton<MonoManeger>
{
MonoController monoCtrler;
/// <summary>
/// 构造函数,用于初始化MonoController对象
/// 先在场景中生成一个游戏对象,然后为它添加 MonoController脚本
/// </summary>
public MonoManeger()
{
GameObject gameObj = new GameObject("monoController");
gameObj.AddComponent<MonoController>();
}
/// <summary>
/// 提供给外部,获取 添加要进行帧更新函数的 方法
/// </summary>
/// <param name="func">要添加帧更新的函数</param>
public void AddUpdateListener(UnityAction func)
{
monoCtrler.AddUpdateListener(func);
}
/// <summary>
/// 提供给外部,获取 移除不进行帧更新函数的 方法
/// </summary>
/// <param name="func">要移除帧更新的函数</param>
public void RemeveUpdateListerner(UnityAction func)
{
monoCtrler.RemeveUpdateListerner(func);
}
}
③ 没有继承MonoBehavior的类也可以使用协程方法
和统一管理Update的方法类似,由于MonoController继承自MonoBehavior,那么我们只需要在MonoManager类里把monoCtrler字段的协程方法封装起来即可。
具体封装方法就是照着monoCtrler中的协程方法的格式修改。
代码
public Coroutine StartCoroutine(string methodName)
{
return monoCtrler.StartCoroutine(methodName);
}
public Coroutine StartCoroutine(IEnumerator routine)
{
return monoCtrler.StartCoroutine(routine);
}
public Coroutine StartCoroutine(string methodName, [DefaultValue("null")] object value)
{
return monoCtrler.StartCoroutine(methodName, value);
}
public Coroutine StartCoroutine_Auto(IEnumerator routine)
{
return monoCtrler.StartCoroutine_Auto(routine);
}
public void StopAllCoroutines()
{
monoCtrler.StopAllCoroutines();
}
public void StopCoroutine(IEnumerator routine)
{
monoCtrler.StopCoroutine(routine);
}
public void StopCoroutine(Coroutine routine)
{
monoCtrler.StopCoroutine(routine);
}
public void StopCoroutine(string methodName)
{
monoCtrler.StopCoroutine(methodName);
}
问题
关于视频中有提到,invoke定时执行的函数不可以像上述那样的方法来实现封装,不是很理解是为什么?