這幾天折騰一個和米仔一起玩的桌游,是丟骰子走路的游戲袍啡。
雖然是用Unity開發(fā),但是里面遇到一些問題處理不是很方便却桶。
例如丟骰子境输,行走到一個格子上觸發(fā)事件,播放動畫后執(zhí)行邏輯颖系。這些東西并不復(fù)雜嗅剖,但是邏輯都是異步的,用delegate回調(diào)寫起來總覺得繞圈嘁扼,容易出錯窗悯。
一直在想有沒有辦法用協(xié)程來實現(xiàn)這個功能,我希望的主邏輯函數(shù)能這么寫:
void Function()
{
? ?丟骰子
? ?走幾步
? ?如果有出發(fā)事件偷拔,處理事件
? ?播放相機(jī)切換動畫,換下一個角色
}
正常的阻塞式函數(shù)是沒法這么寫的亏钩,因為會被動畫等操作卡住莲绰。但是用協(xié)程處理起來就方便多了。
Unity只支持它特定的幾個函數(shù)姑丑,沒法寫做到丟完骰子后走幾步蛤签,因為丟骰子是有物理動畫的。
幾年前問過Unity中國的程序栅哀,如何定制協(xié)程函數(shù)震肮,給的答案是要改源代碼称龙。
在網(wǎng)上搜了搜,沒想到Unity從5.3版本加入了一個新的類CustomYieldInstruction戳晌,從它派生就好了鲫尊。
在Unity的文檔中還專門舉了個例子:
public class WaitUntil : CustomYieldInstruction
{
??Func<bool> action_ = null;
??public WaitUntil(Func<bool> action)
??{
????action_ = action;
??}
??public override bool keepWaiting
??{
????get
????{
??????return action_();
????}
??}
}
這是個通用的等待函數(shù),那么我的代碼就可以這么寫了
IEnumerator Function()
{
?dice.Throw();
?yield return new WaitUntil(()=> dice.animation == false);
?dino.Walk();
?yield return new WaitUntil(()=>dino.stop == true);
?if (current_pos.HasEvent())
??DoEvent();
?camera.SwitchPlayer();
?yield return new WaitUntil(()=>camera.stop == true);
}
這邏輯寫起來清晰多了沦偎。在一個函數(shù)中描述完成所有的行為疫向,不用將控制代碼分散到各處了,連狀態(tài)控制都省了豪嚎。
最后派生IEnumerator這個接口也可以搔驼。