機能: 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;
}
}
}