本篇我们通过使用单例模式来创建一个公共执行器,使得原本应该在Update()、FixedUpdate()中的指令都可以统一放在一个对象中执行,且可进行添加和移除操作。
1. 创建单例模式改造器:SingletonMono
我们先创建一个单例模式改造器,使得其它类想要使用单例模式都可以直接继承该类:
using UnityEngine;
public class SingletonMono<T> : MonoBehaviour where T : SingletonMono<T>
{
public static T Instance;
protected virtual void Awake()
{
if (Instance == null)
{
Instance = (T)this;
}
else
{
Destroy(gameObject);
}
}
}
2. 公共执行器:MonoManager
关于 PlayerInputControl 类的相关解释可参考文章:[步骤] 启用Unity全新输入系统。
using System;
using UnityEngine;
public class MonoManager : SingletonMono<MonoManager>
{
[HideInInspector] public PlayerInputControl input;
private void OnEnable()
{
if (input == null)
input = new PlayerInputControl();
input.Enable();
}
private void OnDisable()
{
input?.Disable();
}
private Action updateAction;
private Action lateUpdateAction;
private Action fixedUpdateAction;
public void AddUpdateListener(Action action)
{
updateAction += action;
}
public void RemoveUpdateListener(Action action)
{
updateAction -= action;
}
public void AddLateUpdateListener(Action action)
{
lateUpdateAction += action;
}
public void RemoveLateUpdateListener(Action action)
{
lateUpdateAction -= action;
}
public void AddFixedUpdateListener(Action action)
{
fixedUpdateAction += action;
}
public void RemoveFixedUpdateListener(Action action)
{
fixedUpdateAction -= action;
}
private void Update()
{
updateAction?.Invoke();
}
private void LateUpdate()
{
lateUpdateAction?.Invoke();
}
private void FixedUpdate()
{
fixedUpdateAction?.Invoke();
}
}
3. 测试:TestMonoManager
using System.Collections;
using UnityEngine;
public class TestMonoManager : MonoBehaviour
{
Coroutine coroutine;
private void Start()
{
MonoManager.Instance.AddUpdateListener(TestUpdate);
MonoManager.Instance.AddFixedUpdateListener(TestFixedUpdate);
MonoManager.Instance.AddFixedUpdateListener(TestLateUpdate);
coroutine = MonoManager.Instance.StartCoroutine(TestCoroutine());
}
private void TestUpdate()
{
print("正在执行Update");
}
private void TestFixedUpdate()
{
print("正在执行FixedUpdate");
}
private void TestLateUpdate()
{
print("正在执行LateUpdate");
}
private IEnumerator TestCoroutine()
{
while (true)
{
yield return new WaitForSeconds(0.1f);
print("正在执行TestCoroutine");
// 当用户按下<移动键>则停止执行该协程
if (MonoManager.Instance.input.Player.Move.ReadValue<Vector2>() != Vector2.zero)
{
MonoManager.Instance.StopCoroutine(coroutine);
}
}
}
}