初学者,自用笔记
基于事件中心
// Mono控制器:提供生命周期事件监听和协程管理功能
public class MonoController : MonoBehaviour
{
// 无参Update事件委托
private event Action updateEvent;
// 协程字典:存储协程标识与对应协程引用,用于精准管理协程
private Dictionary<string, Coroutine> _coroutineDict = new Dictionary<string, Coroutine>();
public static MonoController Instace;
private void Awake()
{
Instace = this;
}
void Start()
{
}
// Unity每帧执行:触发注册的Update事件
void Update()
{
if(updateEvent!=null)
{
updateEvent();
}
}
// 启动协程(带标识):避免重复启动同名协程
public void StartCoroutineEx(string key, IEnumerator routine)
{
// 若已存在同名协程,先停止再重启
if (_coroutineDict.ContainsKey(key))
{
StopCoroutineEx(key);
}
// 存储协程引用并启动
_coroutineDict[key] = StartCoroutine(routine);
}
// 停止指定标识的协程:并清理字典记录
public void StopCoroutineEx(string key)
{
if (_coroutineDict.TryGetValue(key, out Coroutine coroutine))
{
StopCoroutine(coroutine); // 停止协程
_coroutineDict.Remove(key); // 移除无效记录
}
}
// 添加Update事件监听
public void AddUpdateListener(Action _fun)
{
updateEvent += _fun;
}
// 移除Update事件监听
public void RemoveUpdateListener(Action _fun)
{
updateEvent -= _fun;
}
}
基于接口
// 执行接口,方便进行依赖注入
public interface IUpdateLoop
{
void RegisterUpdate(IUpdateable u);
void UnregisterUpdate(IUpdateable u);
void RegisterFixed(IFixedUpdateable f);
void UnregisterFixed(IFixedUpdateable f);
}
public interface ICoroutineRunner
{
void StartCoroutineEx(string key, IEnumerator routine);
void StopCoroutineEx(string key);
void StopCoroutinesByPrefix(string prefix);
}
// 使用方,帧更新接口
public interface IUpdateable { void OnUpdate(); }
// 使用方,物理帧更新接口
public interface IFixedUpdateable { void OnFixedUpdate(); }
public class MonoController : MonoBehaviour
{
[SerializeField] private MonoController myMono;
// 存储需要帧更新的实例(IUpdateable)
private List<IUpdateable> _updateables = new List<IUpdateable>();
// 存储需要物理帧更新的实例(IFixedUpdateable)
private List<IFixedUpdateable> _fixedUpdateables = new List<IFixedUpdateable>();
// 协程管理字典
private Dictionary<string, Coroutine> _coroutineDict = new Dictionary<string, Coroutine>();
#region Update
public void RegisterUpdate(IUpdateable updateable)
{
if (updateable != null && !_updateables.Contains(updateable))
{
_updateables.Add(updateable);
}
}
public void UnregisterUpdate(IUpdateable updateable)
{
if (_updateables.Contains(updateable))
{
_updateables.Remove(updateable);
}
}
#endregion
#region FixedUpdate
public void RegisterFixedUpdate(IFixedUpdateable fixedUpdateable)
{
if (fixedUpdateable != null && !_fixedUpdateables.Contains(fixedUpdateable))
{
_fixedUpdateables.Add(fixedUpdateable);
}
}
public void UnregisterFixedUpdate(IFixedUpdateable fixedUpdateable)
{
if (_fixedUpdateables.Contains(fixedUpdateable))
{
_fixedUpdateables.Remove(fixedUpdateable);
}
}
#endregion
#region 协程管理
public void StartCoroutineEx(string key, IEnumerator routine)
{
if (string.IsNullOrEmpty(key) || routine == null) return;
if (_coroutineDict.ContainsKey(key))
{
StopCoroutineEx(key);
}
_coroutineDict[key] = StartCoroutine(routine);
}
public void StopCoroutineEx(string key)
{
if (string.IsNullOrEmpty(key)) return;
if (_coroutineDict.TryGetValue(key, out Coroutine coroutine))
{
StopCoroutine(coroutine);
_coroutineDict.Remove(key);
}
}
// 停止所有以指定前缀开头的协程
public void StopCoroutinesByPrefix(string prefix)
{
if (string.IsNullOrEmpty(prefix)) return;
var keysToRemove = new List<string>();
foreach (var kvp in _coroutineDict)
{
if (kvp.Key.StartsWith(prefix))
{
StopCoroutine(kvp.Value);
keysToRemove.Add(kvp.Key);
}
}
foreach (var key in keysToRemove)
{
_coroutineDict.Remove(key);
}
}
#endregion
#region Unity 生命周期 统一驱动
private void Update()
{
for (int i = 0; i < _updateables.Count; i++)
{
_updateables[i]?.OnUpdate();
}
}
private void FixedUpdate()
{
for (int i = 0; i < _fixedUpdateables.Count; i++)
{
_fixedUpdateables[i]?.OnFixedUpdate();
}
}
#endregion
// 清理无效引用(场景切换/对象销毁时调用,避免冗余)
public void CleanupInvalid()
{
_updateables.RemoveAll(item => item == null);
_fixedUpdateables.RemoveAll(item => item == null);
_coroutineDict.Clear();
}
}

京公网安备 11010502036488号