# YuriFrameWork ## 目的 * 彼此好維護:確保一致性、易讀性 * 執行效能更好:了解執行成本 * 更安全:避免掉不安全的作法 * 減少專案交接時,由於程式碼風格水土不服所帶來的風險。 * 可以減少加人時所帶來的人力浪費(可以讓一個人花更少的時間去看懂某個專案的程式碼)。 * 防止專案過了一段時間一些實現自己都看不懂了。 ## 規範說明 * 邏輯基於MVC Model用於共通資料的存儲,且提供取用的Method。 View為Unity的視圖,無腳本。 System負責複雜的資料處理邏輯,處理完邏輯將資料存入Model供Controller取用。 Controller用於View邏輯處理,通常會需要[SerializeField]等,所以會繼承MonoBehaviour掛在場景物件上,調用System處理資料,並從Model取用。 腳本命名 Controller為有控制用途的Contorller,其他屬於MVC Controller的腳本不加Controller Manager為有總管理責任的Contorller,通常只會有一個,掛在場景物件上。 * 需依賴DI框架,目前選用Reflax(速度較快、效能較好) * 需要給其他腳本調用的腳本需宣告介面並宣告Public的Value或Method,透過DI綁定以上介面實作,在需調用的腳本利用DI注入 這樣若需要替換實作只要更換綁定的實作就可以了,不用動到其他參考。 * 遵守CodeStyle : [C# code style in Unity](/la-Yl84qQ9uBDIvTB6pULw) * 工具們 : [Unity Tools](https://hackmd.io/@zyr09/HJLKNYo-0) * Unity問題整合 : [Unity 避坑指南](/KAe7n5XKTpOwdAh5ESL0Vw) * Disign Pattens筆記: [Game Programming Patterns](/ckfUyWozT52HOwGEEX5WCQ) ## 開始使用 1. Unity安裝Reflax https://github.com/gustavopsantos/Reflex?tab=readme-ov-file#-installation 2. 在專案內Assets/Resources添加Prefab Reflex/ProjectScope 此物件用於執行全域的綁定 3. 場景上新增物件並掛上腳本 SceneScope.cs 一定要掛否則ProjectScope.cs不會啟動 4. 撰寫Installer.cs 全域綁定物件腳本掛到 ProjectScope.cs 同物件下 場景綁定物件腳本掛到 SceneScope.cs 同物件下 Sample綁定 ``` using Reflex.Core; using UnityEngine; public class MainSceneInstaller : MonoBehaviour, IInstaller { [Header("Manager")] [SerializeField] private DialogManager dialogManager; public void InstallBindings(ContainerBuilder builder) { //Model builder.AddSingleton(new PlayerModel(), typeof(PlayerModel)); builder.AddSingleton(new DialogModel(), typeof(DialogModel)); //System builder.AddSingleton(new DialogSystem(builder.Build()), typeof(IDialogSystem)); //Manager builder.AddSingleton(dialogManager, typeof(IDialogManager)); } } ``` 其他腳本注入 ``` [Inject] private IPlayerModel playerModel; ``` [Inject]發生在遊戲周期的Awake之前,且為MonoBehaviour掛在場上的物件上,以下特殊狀況 * 物件如果是Awake後才生成的需要手動注入 ``` [Inject] private ViewManager viewManager; private void Awake() { GameObjectInjector.InjectObject(gameObject, MainSceneInstaller.instance.container); } ``` * 物件不是MonoBehaviour,在建構函數注入範例 ``` public DialogSystem(Container container) { dialogModel = container.Single<DialogModel>(); } ```