5.Monobehaviour模块

5.Monobehaviour模块


5.1 知识点

Monobehaviour模块的作用

可以统一管理生命周期函数,让没有继承Mono的类可以开启协程或者使用部分生命周期函数

生命周期事件类

  1. 定义 BaseMonoBehaviourLifeCycleEventHandler

    创建一个名为 BaseMonoBehaviourLifeCycleEventHandler 的公共类。

  2. 声明私有成员变量

    声明一个私有成员变量 lifecycleEventHandlers,它是一个 List<UnityAction> 类型的列表,用于存储生命周期事件的处理函数。

  3. 添加事件监听器的方法

    创建一个 AddListener 方法,用于向 lifecycleEventHandlers 列表中添加事件处理函数。

  4. 移除事件监听器的方法

    创建一个 RemoveListener 方法,用于从 lifecycleEventHandlers 列表中移除事件处理函数。

  5. 触发事件的方法

    创建一个 Trigger 方法,用于依次调用 lifecycleEventHandlers 列表中的所有事件处理函数。

  6. 清空事件监听器列表的方法

    创建一个 Clear 方法,用于清空 lifecycleEventHandlers 列表中的所有事件处理函数。

生命周期事件管理器类

  1. 定义 BaseMonoBehaviourManager

    创建一个名为 BaseMonoBehaviourManager 的公共类,继承自 BaseSingletonInMonoBehaviour<BaseMonoBehaviourManager>

  2. 声明私有成员变量

    声明一个私有成员变量 eventHandlerDictionary,它是一个 Dictionary<string, BaseMonoBehaviourLifeCycleEventHandler> 类型的字典,用于存储生命周期事件处理器。

  3. 声明生命周期事件处理器

    声明公共成员变量 onUpdateonFixedUpdateonLateUpdateonDestroy,它们分别是 BaseMonoBehaviourLifeCycleEventHandler 类型的实例,用于处理更新、固定更新、延迟更新和销毁事件。

  4. 初始化方法

    Awake 方法中调用 Init 方法来初始化生命周期事件处理器字典。

  5. 初始化生命周期事件处理器

    创建一个 Init 方法,在该方法中将各个生命周期事件处理器添加到 eventHandlerDictionary 字典中。

  6. 添加事件处理器到字典

    创建一个 AddEventToDictionary 方法,用于将事件处理器添加到 eventHandlerDictionary 字典中。

  7. 更新事件

    重写 Update 方法,在该方法中调用 onUpdate 事件处理器的 Trigger 方法来触发更新事件。

  8. 固定更新事件

    重写 FixedUpdate 方法,在该方法中调用 onFixedUpdate 事件处理器的 Trigger 方法来触发固定更新事件。

  9. 延迟更新事件

    重写 LateUpdate 方法,在该方法中调用 onLateUpdate 事件处理器的 Trigger 方法来触发延迟更新事件。

  10. 销毁事件

    重写 OnDestroy 方法,在该方法中首先调用 onDestroy 事件处理器的 Trigger 方法来触发销毁事件,然后清空 eventHandlerDictionary 字典。

进行测试

  1. 定义 Lesson05_Test 类

    创建一个名为 Lesson05_Test 的类,用于测试协程的使用。

  2. 声明变量

    声明一个私有变量 coroutine,用于存储协程的引用。

    声明一个私有字符串变量 Tag,用于标识日志输出的标签。

  3. 构造函数

    创建构造函数,初始化 Lesson05_Test 类的实例。

  4. 启动协程

    在构造函数中,调用 BaseMonoBehaviourManager.Instance.StartCoroutine 方法启动协程 MyCoroutine,并将返回的协程存储在 coroutine 变量中。

  5. 添加更新事件监听器

    使用 BaseMonoBehaviourManager.Instance.onUpdate.AddListener 方法,添加更新事件的监听器。当更新事件触发时,将会输出日志信息。

  6. 添加销毁事件监听器

    使用 BaseMonoBehaviourManager.Instance.onDestroy.AddListener 方法,添加销毁事件的监听器。当对象销毁时,将会输出日志信息。

  7. 更新事件处理逻辑

    在更新事件监听器中,添加逻辑检测按键输入:

    • 如果按下空格键 (KeyCode.Space),则调用 BaseMonoBehaviourManager.Instance.StopCoroutine 方法停止当前协程。
    • 如果按下字母键 ‘A’ (KeyCode.A),则调用 BaseMonoBehaviourManager.Instance.StartCoroutine 方法启动新的随机协程。
    • 如果按下字母键 ‘S’ (KeyCode.S),则调用 BaseMonoBehaviourManager.Instance.StopAllCoroutines 方法停止所有协程。
  8. 定义自定义协程函数

    创建名为 MyCoroutine 的协程函数,接受一个整数参数 i 和一个字符串参数 str。该协程函数会每隔两秒输出一条日志,并在日志中显示参数 i 和字符串参数。

  9. 定义随机协程函数

    创建名为 RandomCoroutine 的协程函数,接受一个整数参数 i。该协程函数会每隔两秒输出一条日志,并在日志中显示参数 i 的值。

  10. 定义 Lesson05_MonoBehaviour模块 类

创建一个名为 Lesson05_MonoBehaviour模块 的 MonoBehaviour 类,用于测试 BaseMonoBehaviourManager 的示例。

  1. Start 方法

Start 方法中,创建一个 Lesson05_Test 的实例对象,用于测试 BaseMonoBehaviourManager 类的功能。

测试结果


5.2 知识点代码

BaseMonoBehaviourLifeCycleEventHandler

using System.Collections.Generic;
using UnityEngine.Events;


public class BaseMonoBehaviourLifeCycleEventHandler
{
    private List<UnityAction> lifecycleEventHandlers = new List<UnityAction>();

    public void AddListener(UnityAction action)
    {
        lifecycleEventHandlers.Add(action);
    }

    public void RemoveListener(UnityAction action)
    {
        lifecycleEventHandlers.Remove(action);
    }

    public void Trigger()
    {
        for (int i = lifecycleEventHandlers.Count - 1; i >= 0; i--)
        {
            lifecycleEventHandlers[i]?.Invoke();
        }
    }

    public void Clear()
    {
        lifecycleEventHandlers.Clear();
    }
}

BaseMonoBehaviourManager

using System.Collections.Generic;

/// <summary>
/// BaseMonoBehaviourManager 是一个MonoBehaviour行为管理器的单例类。
/// </summary>
public class BaseMonoBehaviourManager : BaseSingletonInMonoBehaviour<BaseMonoBehaviourManager>
{
    // 存储生命周期事件处理器的字典
    private Dictionary<string, BaseMonoBehaviourLifeCycleEventHandler> eventHandlerDictionary =
        new Dictionary<string, BaseMonoBehaviourLifeCycleEventHandler>();

    
    public BaseMonoBehaviourLifeCycleEventHandler onUpdate = new BaseMonoBehaviourLifeCycleEventHandler();
    public BaseMonoBehaviourLifeCycleEventHandler onFixedUpdate = new BaseMonoBehaviourLifeCycleEventHandler();
    public BaseMonoBehaviourLifeCycleEventHandler onLateUpdate = new BaseMonoBehaviourLifeCycleEventHandler();
    public BaseMonoBehaviourLifeCycleEventHandler onDestroy = new BaseMonoBehaviourLifeCycleEventHandler();
    
    
    protected virtual void Awake()
    {
        Init();
    }

    void Init()
    {
        // 添加各个生命周期事件处理器到字典中
        AddEventToDictionary("onUpdate", onUpdate);
        AddEventToDictionary("onFixedUpdate", onFixedUpdate);
        AddEventToDictionary("onLateUpdate", onLateUpdate);
        AddEventToDictionary("onDestroy", onDestroy);
    }

    // 添加事件处理器到字典中
    protected virtual void AddEventToDictionary(string key, BaseMonoBehaviourLifeCycleEventHandler handler)
    {
        if (!eventHandlerDictionary.ContainsKey(key))
        {
            eventHandlerDictionary.Add(key, handler);
        }
    }

    protected virtual void Update()
    {
        onUpdate.Trigger();
    }

    protected virtual void FixedUpdate()
    {
        onFixedUpdate.Trigger();
    }

    protected virtual void LateUpdate()
    {
        onLateUpdate.Trigger();
    }

    protected virtual void OnDestroy()
    {
        onDestroy.Trigger();

        // 清空字典
        eventHandlerDictionary.Clear();
    }
}

Lesson05_Test

using System.Collections;
using UnityEngine;
using Random = UnityEngine.Random;

public class Lesson05_Test
{
    Coroutine coroutine;

    private string Tag = "Lesson05_Test";

    public Lesson05_Test()
    {
        IEnumerator myIEnumerator = MyCoroutine(1, "字符");
        coroutine = BaseMonoBehaviourManager.Instance.StartCoroutine(myIEnumerator);

        
        BaseMonoBehaviourManager.Instance.onUpdate.AddListener(() => { Debug.Log(Tag + "onUpdate"); });

        BaseMonoBehaviourManager.Instance.onDestroy.AddListener(() => { Debug.Log(Tag + "onDestroy"); });

        BaseMonoBehaviourManager.Instance.onUpdate.AddListener((() =>
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                BaseMonoBehaviourManager.Instance.StopCoroutine(coroutine);
            }

            if (Input.GetKeyDown(KeyCode.A))
            {
                IEnumerator randomIEnumerator = RandomCoroutine(Random.Range(0, 10000000));
                BaseMonoBehaviourManager.Instance.StartCoroutine(randomIEnumerator);
            }


            if (Input.GetKeyDown(KeyCode.S))
            {
                BaseMonoBehaviourManager.Instance.StopAllCoroutines();
            }
        }));
    }

    //申明协程函数
    IEnumerator MyCoroutine(int i, string str)
    {
        while (true)
        {
            Debug.Log(Tag + $"自定义的协程函数 i:{i}");

            i++;

            yield return new WaitForSeconds(2f);
        }
    }


    //申明协程函数
    IEnumerator RandomCoroutine(int i)
    {
        while (true)
        {
            Debug.Log(Tag + $"随机协程函数 i:{i}");

            yield return new WaitForSeconds(2f);
        }
    }
}

Lesson05_MonoBehaviour模块

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Lesson05_MonoBehaviour模块 类是一个用于测试 BaseMonoBehaviourManager 的示例 MonoBehaviour。
/// </summary>
public class Lesson05_MonoBehaviour模块 : MonoBehaviour
{
    void Start()
    {
        Lesson05_Test test = new Lesson05_Test();
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏