Unity框架学习--4 Mono管理器

作用:使不继承MonoBehaviour的类能够开启协程,并且可以使用FixedUpdate、Update、LateUpdate进行每帧更新。

原理:
1、在场景中创建一个继承MonoBehaviour的“执行者”脚本,这个脚本就专门用来开启协程和监听帧更新。
2、Mono管理器访问这个“执行者”脚本,就可以实现所需的效果。

创建一个空物体,挂载一个继承自MonoBehaviour 的脚本(没有任何方法也可以)

没有继承的那个脚本代码这样写:

public void Show()
    {
        GameObject go = GameObject.Find("MonoController");
        go.AddComponent<MonoController>().StartCoroutine(MyCoroutine());
    }

    IEnumerator MyCoroutine()
    {
        while (true)
        {
            Debug.Log("协程执行中");
            yield return null;
        }
    }

就可以调用了

Mono管理器开启协程

public class MonoController : MonoBehaviour
{
    
}

MonoManager 管理类,自动创建场景物体并挂载继承有Mono的脚本

继承SingletonPatternBase 作为一个 单例存在

public class MonoManager : SingletonPatternBase<MonoManager>
{
    private MonoManager() { }

    private MonoController monoController;

    public MonoController MonoController
    {
        get
        {
            if (monoController == null)
            {
                GameObject go = new GameObject(typeof(MonoController).Name);
                monoController = go.AddComponent<MonoController>();
            }
            return monoController;
            
        }
    }

    //一个专门让外部用来开启协程的方法
    public Coroutine StartCoroutine(IEnumerator routine)
    {
        return MonoController.StartCoroutine(routine);
    }

Mono管理器停止协程

//停止协程的方法
    public void StopCoroutine(IEnumerator routine)
    {
        MonoController.StopCoroutine(routine);
    }

    //停止协程的方法 重载
    public void StopCoroutine(Coroutine coroutine)
    {
        MonoController.StopCoroutine(coroutine);
    }

    //停止所有协程的方法
    public void StopAllCoroutine()
    {
        MonoController.StopAllCoroutines();
    }
public class Player
{
    Coroutine coroutine;

    public void Show()
    {
        coroutine = MonoManager.Instance.StartCoroutine(MyCoroutine());
    }

    public void Hide()
    {
        MonoManager.Instance.StopCoroutine(coroutine);
    }

    public void HideAll()
    {
        MonoManager.Instance.StopAllCoroutine();
    }

在具体的脚本里直接MonoManager.Instance.xxx方法就可以执行

注意停止协程的写法!!!

Mono管理器Update事件监听

利用委托事件,传递方法进去执行

执行者脚本

/// <summary>
/// 执行者脚本。其他脚本可以通过它来开启停止协程,也可以通过它来监听Update,FixedUpdate。LateUpdate
/// </summary>
public class MonoController : MonoBehaviour
{
    //在生命周期方法中执行的时间
    event UnityAction updateEvent;

    private void Update()
    {
        updateEvent?.Invoke();
    }

    public void AddUpdateListener(UnityAction call)
    {
        updateEvent += call;
    }

    public void RemoveUpdateListener(UnityAction call)
    {
        updateEvent -= call;
    }

    public void RemoveAllUPdateListeners()
    {
        updateEvent = null;
    }

管理者脚本

//添加Update事件
    public void AddUpdateListener(UnityAction call)
    {
        monoController.AddUpdateListener(call);
    }

    //移除Update事件
    public void RemoveUpdateListener(UnityAction call)
    {
        monoController.RemoveUpdateListener(call);
    }

    //移除所有Update事件
    public void RemoveAllUPdateListeners()
    {
        monoController.RemoveAllUPdateListeners();
    }

具体的需要执行的方法的脚本传递委托脚本

public void PrintUpdate()
    {   //添加可以添加Lambda 表达式,但是无法从委托列表中删掉这个Lambda表达式  
        //所以一般不是很简单的逻辑不建议使用lambda表达式
        //可以声明为一个专门的方法然后添加进去
        //lambd 表达式
        MonoManager.Instance.AddUpdateListener(() => 
        { 
            Debug.Log("Update"); 
        });
    }

    public void StopPrintUpdate()
    {                               
        //这个方法是无效的,无法成功删除
        //lambd 表达式
        MonoManager.Instance.RemoveUpdateListener(() =>
        {
            Debug.Log("Update");
        });
    }

    public void StopAllPrintUpdate()
    {
        MonoManager.Instance.RemoveAllUPdateListeners();
    }

Mono管理器优化:嵌套类

很简单,就是把MonoController 声明到 MonoManager 中,没干什么额外的工作

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

public class MonoManager : SingletonPatternBase<MonoManager>
{
    private MonoManager() { }

    private MonoController monoExecuter;

    public MonoController MonoExecuter
    {
        get
        {
            if (monoExecuter == null)
            {
                GameObject go = new GameObject(typeof(MonoController).Name);
                monoExecuter = go.AddComponent<MonoController>();
            }
            return monoExecuter;
            
        }
    }

    //一个专门让外部用来开启协程的方法
    public Coroutine StartCoroutine(IEnumerator routine)
    {
        return MonoExecuter.StartCoroutine(routine);
    }

    //停止协程的方法
    public void StopCoroutine(IEnumerator routine)
    {
        if (routine != null)
        {
            MonoExecuter.StopCoroutine(routine);
        }
    }

    //停止协程的方法 重载
    public void StopCoroutine(Coroutine coroutine)
    {
        if (coroutine != null)
        {
            MonoExecuter.StopCoroutine(coroutine);
        }
    }

    //停止所有协程的方法
    public void StopAllCoroutine()
    {
        MonoExecuter.StopAllCoroutines();
    }

    //添加Update事件
    public void AddUpdateListener(UnityAction call)
    {
        monoExecuter.AddUpdateListener(call);
    }

    //移除Update事件
    public void RemoveUpdateListener(UnityAction call)
    {
        monoExecuter.RemoveUpdateListener(call);
    }

    //移除所有Update事件
    public void RemoveAllUPdateListeners()
    {
        monoExecuter.RemoveAllUPdateListeners();
    }

    /// <summary>
    /// 执行者脚本。其他脚本可以通过它来开启停止协程,也可以通过它来监听Update,FixedUpdate。LateUpdate
    /// </summary>
    public class MonoController : MonoBehaviour
    {
        //在生命周期方法Update中执行的事件
        event UnityAction updateEvent;

        //在生命周期方法FixUpdate中执行的事件
        event UnityAction fixUpdateEvent;

        private void FixedUpdate()
        {
            fixUpdateEvent?.Invoke();
        }

        private void Update()
        {
            updateEvent?.Invoke();
        }

        public void AddUpdateListener(UnityAction call)
        {
            updateEvent += call;
        }

        public void RemoveUpdateListener(UnityAction call)
        {
            if (updateEvent != null)
            {
                updateEvent -= call;
            }
        }

        public void RemoveAllUPdateListeners()
        {
            updateEvent = null;
        }

        public void AddFixUpdateListener(UnityAction call)
        {
            fixUpdateEvent += call;
        }

        public void RemoveFixUpdateListener(UnityAction call)
        {
            if (fixUpdateEvent != null)
            {
                fixUpdateEvent -= call;

            }
        }

        public void RemoveAllFixUpdateListeners()
        {
            fixUpdateEvent = null;
        }
    }

}

猜你喜欢

转载自blog.csdn.net/zaizai1007/article/details/132284672