Unity framework learning--4 Mono manager

Function : Enable classes that do not inherit MonoBehaviour to start coroutines, and use FixedUpdate, Update, and LateUpdate to update each frame.

Principle:
1. Create an "executor" script that inherits MonoBehaviour in the scene. This script is specifically used to start the coroutine and monitor frame updates.
2. The Mono manager accesses this "executor" script to achieve the desired effect.

Create an empty object and mount a script inherited from MonoBehaviour (you can do it without any method)

The script code without inheritance is written like this:

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

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

You can call it

Mono manager starts coroutine

public class MonoController : MonoBehaviour
{
    
}

MonoManager management class, automatically creates scene objects and mounts scripts that inherit Mono

Inherits SingletonPatternBase and exists as a singleton

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 manager stops coroutine

//停止协程的方法
    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();
    }

The MonoManager.Instance.xxx method can be executed directly in the specific script.

Pay attention to the way to stop the coroutine! ! !

Mono manager Update event listening

Use delegate events to pass methods for execution

executor script

/// <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;
    }

manager script

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

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

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

The script of the specific method that needs to be executed passes the delegate script

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 manager optimization: nested classes

It's very simple, just declare MonoController into MonoManager, no extra work is done

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;
        }
    }

}

Guess you like

Origin blog.csdn.net/zaizai1007/article/details/132284672