(2014年舊文)
今年工作的很多內(nèi)容是編輯器涩馆,給策劃做的編輯器,給美術(shù)做的編輯器烫沙,各種小工具等匹层,
我想,工具和編輯器在今天更成為游戲開發(fā)中重要的手段锌蓄,
- 更精確升筏,更好的表現(xiàn)力制作;
-
把人從枯燥重復(fù)的工作中解脫出來,進(jìn)入到一個(gè)高效愉悅的工作流;
unity/UE這些游戲引擎瘸爽,它們既不是渲染最好的您访,也不是效率最好的,但他們真正吸引之處是在于它們編輯器的強(qiáng)大剪决,未來灵汪,也許是一個(gè)面向工具的游戲制作方式呢.
圖1. 動(dòng)畫編輯器
片頭動(dòng)畫檀训,過場(chǎng)動(dòng)畫,算是3D游戲的標(biāo)配吧, 談下編輯器的UI方式享言,
這里使用了unity gui擴(kuò)展峻凫,也就是類似于maya script那樣通過腳本的方式,在主UI上寫擴(kuò)展的菜單览露,擴(kuò)展windows蔚晨,但unity的擴(kuò)展方式還是另人驚奇的,它實(shí)現(xiàn)了一種 Immediate-Mode GUI, 比如說
if(guilayout.button("點(diǎn)擊1")
Debug.log("完成點(diǎn)擊1");
if(guilayout.button("點(diǎn)擊2")
Debug.log("完成點(diǎn)擊2");
很簡(jiǎn)單肛循,這里是兩個(gè)按扭的顯示,和兩個(gè)按鈕的點(diǎn)擊響應(yīng)银择!對(duì)于沒有其它GUI經(jīng)驗(yàn)的人似乎很自然多糠,但細(xì)思極恐......它如何做到無阻塞地做到GUI顯示和響應(yīng)的呢, google之: Immediate-Mode GUI......
另一個(gè)例子浩考,GUILayout.BeginVertical()//垂直UI排版夹孔,if(guilayout.button("點(diǎn)擊1")....if(guilayout.button("點(diǎn)擊n")....GUILayout.EndVertical()這似乎破壞了多年GUI的實(shí)踐的共識(shí)——布局與邏輯分離,不過使用起來卻很舒服析孽,看起來“不合規(guī)矩”的設(shè)計(jì)搭伤,在合適的場(chǎng)景都是有用的。unity擴(kuò)展是極好的袜瞬,但也體驗(yàn)了不少坑怜俐,
- 一些細(xì)節(jié),比如說untiy的輸入框(中文輸入)是有問題的邓尤,
- 一些限制拍鲤,GUI樣式缺乏,無法多窗口控制汞扎,你最好只做在一個(gè)窗口上季稳,
- 一些無力,這種immd mode的GUI澈魄,把UI和邏輯混大一塊景鼠,渲染和用戶輸入同一循環(huán),你會(huì)發(fā)覺越寫越吃力痹扇,越寫繪制性能越壞...
-
一些考慮铛漓,擴(kuò)展腳本方式,編輯器代碼暴露在外;在技能編輯器里鲫构,我考慮了另一種方式票渠,以獨(dú)立工具形式提供的編輯器,可是芬迄,unity是一個(gè)封閉的開發(fā)環(huán)境问顷,這怎么做呢?
圖2. 技能編輯器,WPF + unity exe杜窄,..這里可談的兩點(diǎn)肠骆,
一. WPF
WPF教會(huì)了我很好的GUI,和編輯器的設(shè)計(jì)方式,這超越了我之前對(duì)GUI的認(rèn)識(shí),上升到理論高度就是塞耕,
- 高度交互的程序蚀腿,其實(shí)是個(gè)”約束傳播模型“,就是一個(gè)值(輸入扫外,對(duì)象) 的變化莉钙,會(huì)傳播到系統(tǒng)的各處,那么其實(shí)需要做好的筛谚,就是建立這種約束模型磁玉,在WPF層面上,對(duì)應(yīng)的就是”依賴屬性”之類的概念;
- 模型映射驾讲,對(duì)象模型如何對(duì)應(yīng)表現(xiàn)層蚊伞?從表現(xiàn)到模型 需要建立一種 “同態(tài)”的映射,你一定會(huì)想到MVC之類的模式吮铭,WPF推薦的是一種MVVM方案时迫,我理解的就是,重視view-mode層谓晌,以這個(gè)接口層去控制 view 和 mode兩個(gè)模型掠拳,它既不會(huì)像view那樣有著表現(xiàn)的具體實(shí)現(xiàn),又不會(huì)像model那樣是塊無傳播約束的數(shù)據(jù)纸肉,它建立的是約束模型碳想,驅(qū)動(dòng)model, 會(huì)雙向映射到view, ——不知你懂我意思了沒,一切以官方mvvm說明毁靶。
二. 進(jìn)程交互剛開始胧奔,我也在想,我如何處理如此多的交互類型呢预吆,我又如何去做到異步交互呢龙填,但當(dāng)我看到WCF(你沒聽過的話,想想同樣是MS技術(shù)的WPF)的方案時(shí)拐叉,問題就不大了岩遗,WCF提供了 c#的RPC方案,因此凤瘦,并發(fā)程序可以像單個(gè)進(jìn)程那樣實(shí)現(xiàn)了宿礁,
定義一個(gè) unity服務(wù),
interface IUnity
{
}
和一個(gè) editor服務(wù)蔬芥,
interface IEditor
{
}
壞的事情是梆靖,當(dāng)我們工程升級(jí)到 unity 4.6時(shí)控汉,mono提供的WCF終于不能用了(且不說它之前總是死鎖,有些模式未提供什么的)返吻,我只好實(shí)現(xiàn)自己的RPC方案,
最后姑子,我發(fā)覺這異常好用,
//editor 進(jìn)程
IUnity unityProxy = new Service.Client<IUnity>("127.0.0.1", 10086).getProxy();
unityProxy.loadScene(...)......
//unity 進(jìn)程
var unityServer = new Service.Server<IUnity>(10086, new UnityImpl() );
unityServer.run()
我設(shè)計(jì)了 CPS(continue pass style) 方式的接口测僵,處理異步.
//cont(true/false) 返回是否成功
void loadScene(string fpath, System.Action<object> cont);
如此街佑,我希望能夠在交互程序設(shè)計(jì)這塊,探索出更好的經(jīng)驗(yàn)
(2014年舊文)