前段時(shí)間接到一個(gè)批處理FBX默認(rèn)材質(zhì)的任務(wù),它需要在Unity回調(diào)中執(zhí)行才能起作用。由于我的批處理邏輯和回調(diào)不是順序執(zhí)行祭玉,要得到正確的效果就需要等待一點(diǎn)時(shí)間拴念,保證一個(gè)FBX處理完后才處理下一個(gè)钧萍。
經(jīng)過(guò)一番搜索找到了Editor下每幀執(zhí)行的Update回調(diào)EditorApplication.update。Unity提供這個(gè)接口丈莺,是方便了我們,但是回調(diào)的形式有時(shí)卻很繁瑣……用的時(shí)候要+=送丰,用完可能還要 -=缔俄。這里我想到了用Update來(lái)模擬協(xié)程,把繁瑣的事情變成一次性的器躏,就不能算繁瑣~~
下面上代碼:
/// <summary>
/// UnityEditor下模擬協(xié)程
/// </summary>
public class EditorCoroutine
{
/// <summary>
/// 迭代列表
/// </summary>
private static List<IEnumerator> _itors = null;
/// <summary>
/// 要從迭代列表中移除的索引
/// </summary>
private static List<int> _removeIdxs = null;
private static EditorApplication.CallbackFunction _updateFunc = null;
/// <summary>
/// Update方法是否在執(zhí)行
/// </summary>
private static bool _isUpdateRuning = false;
static EditorCoroutine()
{
_itors = new List<IEnumerator>();
_removeIdxs = new List<int>();
_updateFunc = _Update;
}
public static void Start(IEnumerator itor)
{
_itors.Add(itor);
_RunUpdate(true);
}
private static void _RunUpdate(bool isRun)
{
if (isRun == _isUpdateRuning) return;
// 運(yùn)行Update
if (isRun)
{
EditorApplication.update += _updateFunc;
}
// 停止運(yùn)行Update
else
{
EditorApplication.update -= _updateFunc;
}
_isUpdateRuning = isRun;
}
private static void _Update()
{
if (null == _itors || _itors.Count <= 0) return;
for (int i = 0, c = _itors.Count; i < c; ++i)
{
if (!_itors[i].MoveNext())
{
_removeIdxs.Add(i);
}
}
if (_removeIdxs.Count <= 0) return;
for (int i = _removeIdxs.Count - 1; i >= 0; --i)
{
_itors.RemoveAt(_removeIdxs[i]);
_removeIdxs.RemoveAt(i);
}
if (_itors.Count == 0)
{
_RunUpdate(false);
}
}
}