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 マネージャー更新イベントのリスニング

デリゲート イベントを使用して実行用のメソッドを渡す

実行スクリプト

/// <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 マネージャーの最適化: ネストされたクラス

非常に簡単です。MonoManager に MonoController を宣言するだけで、追加の作業は行われません。

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
おすすめ