支援分離程式碼和UI資源的Unity Lua介面框架
概述
所謂分離程式碼和UI資源說白了就是為了程式不拼UI,而專心在程式碼上。MVVM模式是個很好的參考,它的優點有
unity中有一些MVVM的框架,比如uFrame、Unity-Weld,但都是C#的,我需要lua的方案。c#的實現方式可以參考這篇文章。
思考
為了實現lua的方案我有以下幾個思考
- 程式碼中UI物件的變數名應該誰來確定?當然是程式來定好,所以不能依賴於美術做出來的UI
- 如何獲取UI物件的引用?採用自動生成lua程式碼的方式最好
- 程式和美術間的依賴關係是怎樣的?最好是儘早解除依賴並行開發,不要程式等著美術拼完介面
- 如何實現程式碼和資源的隔離?C#方案都是通過事件機制,lua有動態型別和元表更方便實現
- 如何在沒有UI資源的情況下執行程式碼?不能直接使用UI物件,得封裝一層,還得能支援UI控制元件的大多數屬性、方法和回撥。
方案
綜合以上幾條,設計方案如下:
- 製作一個UI的第一步是程式寫UIViewBinding(也可以叫做UI協議),每一項包括變數名、控制元件型別、控制元件引用。控制元件引用可以留空,等UI製作完畢再拖拽或按約定半自動繫結。如下圖

- 匯出:生成繫結程式碼和UIPrefab。自此UI工作流就解耦了,拼介面一般不會改UIViewBinding,需要改就由程式改一下再匯出即可,變數名可以保持不變。美術每次改完介面也需要匯出。生成的BaseUIViewXXX程式碼大概如下:

匯出時會將控制元件引用序列化到prefab上,框架會在UI開啟是呼叫OnCreated,執行期直接獲取引用。有點選事件發生時框架會直接呼叫OnClick_BtnLogin()。程式在BaseUIViewXXX的子類上寫邏輯。
- 為了達到隔離,對每個UI物件都進行封裝,生成程式碼會變成下面的樣子

多出了一個UIcontrollBinder,它內部持有coms[n]的引用,配合元表,在coms[n]為nil時屬性賦值會寫到元表裡,之後的程式碼也能讀的到。元表的好處就是支援任何屬性的讀寫,不用考慮這個屬性是什麼。某些控制元件的重要方法可以在UIcontrollBinder裡單獨實現一個純邏輯的,比如我們用到的tableView的AddData方法,這樣的方法沒幾個。可以有開關控制UIcontrollBinder不起任何作用直接返回coms[n],在最終釋出時不產生額外代價。這套隔離機制要求不能在lua對UI物件執行.gameObject操作,只能讀寫第一層屬性,呼叫第一層的方法。
總結
目前這套機制執行良好,也在不斷的完善,程式碼量仍然不大,也需要專案進一步的考驗。
配合一套lua寫測試用例,遊戲自動執行的機制,就可以主動呼叫button處理函式的執行。反正介面拼完之前沒法手動點點點測試,只能強迫寫用例自測,也許能積累下很多用例,以後迴歸測試還用得著。當然維護用例是有代價的,但如果代價比手動自測要低就已經是很好的開始和趨勢了。
參考
- ofollow,noindex" target="_blank"> https:// zhuanlan.zhihu.com/p/26 799645
- https://www. cnblogs.com/iammackong/ articles/3312565.html
- http://www. what-could-possibly-go-wrong.com /bringing-mvvm-to-unity-part-2-property-and-event-bindings/
- http://www. cnblogs.com/OceanEyes/p /unity3d_framework_designing_get_started_with_mvvm_part1.html