簡體   English   中英

在Unity3D中管理復雜的預制層次結構

[英]Managing complex prefab hierarchies in Unity3D

我在幾個地方問過這個問題,但還沒有完全弄明白,所以也許這里的一些聰明人會知道如何處理這個問題。

在項目中維護預制件的深層嵌套層次結構的最佳方法是什么? 比如,我們有一些GUI屏幕,由較小的通用組件組成。 為簡單起見,我們稱之為前“視圖”,后者稱為“組件”。 視圖處理語義(例如庫存視圖,商店視圖); 組件是可配置的,但沒有任何業務邏輯連接到它們(例如,一個按鈕只關心它的OnTap回調/事件處理程序)。

視圖和組件都可以嵌套。

GUI視圖需要在多個場景中重用。

Unity中這種方法的主要問題是,任何嵌套的層次結構一旦變成預制件,就會丟失對其子預制件的引用,就像在這個(完全組成但仍然有效)的示例中一樣:

- storeView - UIViewHeader - UIHeaderLabel<Text> - UIList - UIListItem - UIThumbnail - UITitleLabel<Text> - UISubTitleLabel<Text> - UIPrimaryButton<Button> - ...

我想將所有這些小UI *組件保存在單獨的預制件中,同時保留storeView預制件,以便我可以輕松地將其添加到不同的場景中。 不幸的是,在我們創建storeView預制件時,很快就會丟失所有UI *預制件引用。 鑒於此,我們可以嘗試一種不同的方法,其中不是使用storeView預制內容,而是將其保持為空並選擇以下幾個選項之一:

  1. 將行為附加到storeView並在運行時加載子預制件
    • 缺點:使設計人員的工作流程更加復雜,將復雜性放在腳本中,從開發角度來看也可能更容易出錯
    • 優點:可以更輕松地在場景之間重用storeView,組件預制件可以進行樣式設置,全局修改
  2. 將storeView保留為空預制件,並在需要它的每個場景中重新組裝
    • 缺點:組件需要手動連接,仍然很容易意外地保存整個storeView並丟失預制參考
    • 優點:保證組件預制引用被維護,允許視圖之間的細微差別(實際上這是一個問題,因為這些應該屬於配置層)
  3. 將整個storeView保存為預制件
    • 缺點:非常嚴重,使新功能或小型UX更改的迭代更耗時(額外的QA,驗收測試等...)
    • 專業人士:這是一個快速而骯臟的解決方案,適用於小型項目
  4. 使用Prefab Evolution或類似產品
    • 缺點:我認為包裝將被Nested Prefabs淘汰,這些都在路線圖上? 需要依賴第三方代碼,可能不夠靈活(這里的任何意見,伙計們?)
    • 專業人士:從我見過的很多(混合)評論中,有些評論非常積極。 然而,項目越復雜,這些評論的積極性就越低。
  5. 寫一堆自定義編輯器腳本:
    • 缺點:耗時,也 - 似乎應該由平台提供的東西,即使它主要涉及游戲
    • 專業人士:完全控制行為,開發人員可以通過設計師的反饋進行改進。 有人可能會說,對於實施,測試和設計師友好的工具作為功能要求的規范聽起來像一個好的設計實踐(導致技術債務減少,維護更容易)

這是我個人的,理想主義的,不切實際的解決方案*:

使用組件化體系結構,默認情況下,子預引用引用存儲在復雜的預制件中。 在內部將它們視為UIView和移動(Cocoa)上的子視圖,或React中的組件類或更好的功能組件 - React / Cycle / Elm /與FRP相關的任何東西(是的,我知道這些方法在很多方面都有所不同,但關鍵是可組合性,通過功能組合,裝飾器等等來實現。

  • 缺點:我認為我的困難來自於我缺乏Unity的經驗,並且有一個更明顯的,也許是慣用的解決方案(我很懇請:))
  • 優點:使測試和迭代新功能更容易,使預制件更強大,同時不會失去任何好處(請糾正我,如果我錯了,我仍然熟悉Unity)

  • 請不要認為我期待Unity的所有這些,但這是可能的方向之一,即使其中1%是真的。

為了說清楚,這不是一個關於Unity的咆哮,作為一個以前使用移動(本機)和網絡工作的開發人員,我發現它解決了我解決了多少問題,以及這些解決方案有多荒謬簡單。

我可能會在單獨的場景中維護復合視圖 簡單地將這些場景視為預制件,僅包含給定類的單個原型對象。

使用帶有LoadSceneMode.Additive SceneManager.LoadScene ,您甚至可以創建一些靜態工廠方法,例如:

public class UIStoreView
{
    public static UIStoreView Instance()
    {
        SceneManager.LoadScene("UIStoreView", LoadSceneMode.Additive);
        return GameObject.Find("UIStoreView");
    }
}

通過一些命名對話,您可以實現像storeView = UIStoreView.Instance();

不是通用/可擴展的東西,但至少你有一些輕量級/可維護的東西,直到它們推出嵌套的預制件( 時間軸不確定,如他們所說)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM