前言
在游戏开发中,协程常用于分帧处理一件事情,避免一帧内处理过多导致卡顿。
具体管理
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BaseCoroutineHelper
{
private static BaseCoroutineHelper _instance;
public static BaseCoroutineHelper Instance{
get
{
if(_instance==null)
_instance=new BaseCoroutineHelper();
return _instance;
}
}
sealed class CoroutineCore:Monobehaviour
{
void OnDestroy()
{
StopAllCoroutines();
}
}
private const string COROUTINEHELPER_GO_NAME="CoroutineHelper";
private GameObject _coroutineHelperObj=null;
private static string DEFAULT_COROUTINEHELPER="MainCoroutine";
private Dictionary<string,CoroutineCore> _cores=new Dictionary<string,CoroutineCore>();
private BaseCoroutineHelper()
{
_coroutineHelperObj=new GameObject(COROUTINEHELPER_GO_NAME);
UnityEngine.Object.DontDestroyOnLoad(_coroutineHelperObj);
}
public Coroutine StartCoroutine(string coreName,IEnumerator routine)
{
CoroutineCore curCore=GetOrCreateCoroutineCore(coreName);
return curCore.StartCoroutine();
}
public void StopCoroutine(string coreName,Coroutine routine)
{
CoroutineCore curCore=GetCoroutineCore(coreName);
if(curCore!=null)
{
curCore.StopCoroutine();
}
else
{
Debug.Log("You StopCoroutine with erro coreName"+coreName);
}
}
public void StopCoroutine(string coreName,IEnumerator routine)
{
CoroutineCore curCore=GetCoroutineCore(coreName);
if(curCore!=null)
{
curCore.StopCoroutine();
}
else
{
Debug.Log("You StopCoroutine with erro coreName"+coreName);
}
}
public void StopAllCoroutines(string coreName)
{
CoroutineCore curCore=GetCoroutineCore(coreName);
if(curCore!=null)
{
curCore.StopAllCoroutines();
}
else
{
Debug.Log("Not have this coreName:"+coreName);
}
}
public void StopAllCoroutines()
{
var iter=_cores.GetEnumerator();
while(iter.MoveNext())
{
iter.Current.Value.StopAllCoroutines();
}
}
public Coroutine StartCoroutine(IEnumerator routine)
{
return StartCoroutine(DEFAULT_COROUTINEHELPER,routine);
}
public void StopCoroutine(Coroutine routine)
{
StopCoroutine(DEFAULT_COROUTINEHELPER,routine);
}
public void StopCoroutine(IEnumerator routine)
{
StopCoroutine(DEFAULT_COROUTINEHELPER,routine);
}
public void DestroyCoroutineCore(string coreName)
{
if(_cores.ContainsKey(coreName))
{
CoroutineCore curCore=_cores[coreName];
curCore.StopAllCoroutines();
GameObject.DestroyImmediate(curCore.gameObject);
}
}
private CoroutineCore GetCoroutineCore(string coreName)
{
CoroutineCore curCC=null;
_cores.TryGetValue(coreName,out curCC);
return curCC;
}
private CoroutineCore CreateCoroutineCore(string coreName)
{
GameObject curCoreObj=new GameObject(coreName);
curCoreObj.transform.SetParent(_coroutineHelperObj.transform);
#if UNITY_5 || UNITY_2018
#else
UnityEngine.Object.DontDestroyOnLoad(curCoreObj);
#endif
CoroutineCore curCore = curCoreObj.AddComponent<CoroutineCore>();
_cores.Add(coreName,curCore);
return curCore;
}
private CoroutineCore GetOrCreateCoroutineCore(string coreName)
{
CoroutineCore curCore=GetCoroutineCore(coreName);
if(curCore==null)
{
curCore=CreateCoroutineCore(coreName);
}
return curCore;
}
}