一、前言
在Unity开发中,经常会遇到需要在没有继承MonoBehaviour
的类中使用协程和Update的情况。为了解决这个问题,我们可以使用Mono管理器,该管理器允许非MonoBehaviour
类使用一些常用的Mono方法。在本篇文章中,我们将深入探讨Mono管理器的实现以及如何使用它进行协程管理和Update事件的监听。
二、Mono管理器的结构
Mono管理器分为执行者类和管理类。
执行者类:
MonoController
类是Mono管理器内部的执行者类,它的主要作用是处理非MonoBehaviour
类的更新事件的触发和监听器的管理。具体来说,它充当了一个桥梁。
主要职责:
-
更新事件的触发:
MonoController
中包含了Update
、FixedUpdate
和LateUpdate
等生命周期事件的实现。
当这些事件被触发时,它会调用相应的监听器,执行注册在这些事件上的方法。
2.监听器管理:
MonoController
维护了三个事件类型的监听器,分别用于Update
、FixedUpdate
和 LateUpdate。
提供了添加、移除以及移除所有监听器的方法,以便外部能够动态地注册和取消注册这些事件。
管理类:
MonoManager
是一个管理类,其主要作用是提供一种机制,使那些没有继承MonoBehaviour
的类也能够方便地利用Unity的生命周期事件和协程。
主要职责:
-
协程管理:
MonoManager
通过MonoController
类提供了协程的管理功能,允许非MonoBehaviour
的类通过StartCoroutine
、StopCoroutine
和StopAllCoroutines
方法来开启、停止和停止所有协程。 -
更新事件管理:
提供对Update、FixedUpdate和LateUpdate事件的监听器管理,允许非MonoBehaviour
的类通过AddUpdateListener
、AddFixedUpdateListener
、AddLateUpdateListener
等方法添加相应事件的监听器。同时,提供了移除特定监听器和移除所有监听器的方法。 -
单例模式:
MonoManager
通过继承NoMonoSingleton
类实现了单例模式,确保在整个项目中只有一个MonoManager
的实例。
两者关系:
-
主从关系:
-
MonoManager
是主类,负责对外提供协程管理和更新事件管理的接口。 -
MonoController
是辅助类,被MonoManager
内部使用,负责实际执行协程和触发更新事件。
-
-
协作方式:
-
MonoManager
中包含了一个私有成员变量_monoController
,该变量是MonoController
类的一个实例。 -
MonoManager
通过monoController
属性来获取或创建_monoController
实例,以便在其中执行协程和触发更新事件。
-
-
功能分工:
-
MonoManager
主要负责对外提供协程管理和更新事件管理的方法,以及实现单例模式。 -
MonoController
主要负责实际的协程管理和更新事件的触发,同时作为一个内部类,使得这些功能可以被非MonoBehaviour
的类调用。
-
-
解耦和灵活性:文章来源:https://www.toymoban.com/news/detail-808930.html
- 通过将协程和更新事件的具体实现封装在
MonoController
中,MonoManager
实现了对这些功能的解耦。这意味着,如果将来需要更改协程或更新事件的实现方式,只需修改MonoController
而不影响MonoManager
接口。
- 通过将协程和更新事件的具体实现封装在
三、代码实现:
using System;
using System.Collections;
using Mr.Le.Utility.Singleton;
using UnityEngine;
using UnityEngine.Events;
namespace Mr.Le.Utility.Manager
{
/// <summary>
/// Mono管理器
/// </summary>
public class MonoManager : NoMonoSingleton<MonoManager>
{
private MonoManager()
{
} //防止外部实例化
private MonoController _monoController;
private MonoController monoController
{
get
{
if (_monoController == null)
{
GameObject go = new GameObject(typeof(MonoController).Name);
_monoController = go.AddComponent<MonoController>();
}
return _monoController;
}
}
#region 协程管理
/// <summary>
/// 让外部通过它来开启协程
/// </summary>
/// <param name="coroutine"></param>
/// <returns></returns>
public Coroutine StartCoroutine(IEnumerator coroutine)
{
return monoController.StartCoroutine(coroutine);
}
/// <summary>
/// 让外部通过它来停止协程
/// </summary>
/// <param name="coroutine"></param>
public void StopCoroutine(Coroutine coroutine)
{
monoController.StopCoroutine(coroutine);
}
/// <summary>
/// 让外部通过它来停止所有协程
/// </summary>
public void StopAllCoroutines()
{
monoController.StopAllCoroutines();
}
#endregion
#region Update事件管理
/// <summary>
/// 添加Update事件
/// </summary>
/// <param name="call"></param>
public void AddUpdateListener(UnityAction call)
{
monoController.AddUpdateListener(call);
}
/// <summary>
/// 移除指定Update事件
/// </summary>
/// <param name="call"></param>
public void RemoveUpdateListener(UnityAction call)
{
monoController.RemoveUpdateListener(call);
}
/// <summary>
/// 移除所有Update事件
/// </summary>
public void RemoveAllUpdateListeners()
{
monoController.RemoveAllUpdateListeners();
}
#endregion
#region FixedUpdate事件管理
/// <summary>
/// 添加FixedUpdate事件
/// </summary>
/// <param name="call"></param>
public void AddFixedUpdateListener(UnityAction call)
{
monoController.AddFixedUpdateListener(call);
}
/// <summary>
/// 移除指定FixedUpdate事件
/// </summary>
/// <param name="call"></param>
public void RemoveFixedUpdateListener(UnityAction call)
{
monoController.RemoveFixedUpdateListener(call);
}
/// <summary>
/// 移除所有FixedUpdate事件
/// </summary>
public void RemoveAllFixedUpdateListeners()
{
monoController.RemoveAllFixedUpdateListeners();
}
#endregion
#region LateUpdate事件管理
/// <summary>
/// 添加LateUpdate事件
/// </summary>
/// <param name="call"></param>
public void AddLateUpdateListener(UnityAction call)
{
monoController.AddLateUpdateListener(call);
}
/// <summary>
/// 移除指定LateUpdate事件
/// </summary>
/// <param name="call"></param>
public void RemoveLateUpdateListener(UnityAction call)
{
monoController.RemoveLateUpdateListener(call);
}
/// <summary>
/// 移除所有LateUpdate事件
/// </summary>
public void RemoveAllLateUpdateListeners()
{
monoController.RemoveAllLateUpdateListeners();
}
#endregion
/// <summary>
/// 执行者类
/// </summary>
public class MonoController : MonoBehaviour
{
private event UnityAction updateEvent;
private event UnityAction fixedUpdateEvent;
private event UnityAction lateUpdateEvent;
private void Update()
{
updateEvent?.Invoke();
}
private void FixedUpdate()
{
fixedUpdateEvent?.Invoke();
}
private void LateUpdate()
{
lateUpdateEvent?.Invoke();
}
#region Update中的事件管理
public void AddUpdateListener(UnityAction call)
{
updateEvent += call;
}
public void RemoveUpdateListener(UnityAction call)
{
updateEvent -= call;
}
public void RemoveAllUpdateListeners()
{
updateEvent = null;
}
#endregion
#region FixedUpdate中的事件管理
public void AddFixedUpdateListener(UnityAction call)
{
fixedUpdateEvent += call;
}
public void RemoveFixedUpdateListener(UnityAction call)
{
fixedUpdateEvent -= call;
}
public void RemoveAllFixedUpdateListeners()
{
fixedUpdateEvent = null;
}
#endregion
#region LateUpdate中的事件管理
public void AddLateUpdateListener(UnityAction call)
{
lateUpdateEvent += call;
}
public void RemoveLateUpdateListener(UnityAction call)
{
lateUpdateEvent -= call;
}
public void RemoveAllLateUpdateListeners()
{
lateUpdateEvent = null;
}
#endregion
}
}
}
四、总结
通过使用Mono管理器,我们可以在非MonoBehaviour
类中方便地使用协程和更新事件,提高代码的灵活性和可复用性。希望本篇博客能够帮助你更好地理解和使用Mono管理器,提升Unity开发的效率。文章来源地址https://www.toymoban.com/news/detail-808930.html
到了这里,关于Unity框架-Mono管理器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!