Unity Addressables可尋址資源系統是一個強大的Unity資源包,它能夠幫助解決游戲開發中最重要的一些挑戰:高效率和輕松的內容管理。
在管理游戲資源時,往往很難維持好的標准,從而避免讓項目變得雜亂無章。最主要的問題在於不同職責的資源管理系統之間的耦合。而且,項目中資源的存儲,加載和載入后資源的使用方法都有緊密的聯系。
例如:我們可能要在Resources文件夾存儲某個精靈。這會讓Unity在構建版本時,把精靈存到特定的存檔文件中。由於精靈存在了這樣的位置,我們必須通過Resources API來加載該精靈。
項目變得混亂的速度比你想象的更快,一種方法的選擇將造成項目長期的結果。一個好的系統會避免我們輕易犯下草率的錯誤,一個優秀的系統也會易於學習和使用。
通過使用Unity Addressables可尋址資源系統,我們可以將資源管理問題分離。我們的目標是保持靈活性,同時讓項目具有可維護性。
本文,我們將介紹開發者使用Unity Addressables可尋址資源系統創作游戲時,會獲得的三個好處。
好處1:減少游戲的內存壓力
在發布游戲時,大多數平台都會讓開發者提供玩游戲所需的最低硬件配置要求,以便玩家在購買時參考。
原因很簡單:要求的硬件配置越高,購買游戲的玩家會越少。而從另一個角度看,實現的內存管理越好,我們便可在游戲提供更多內容和樂趣。
Unity Addressables可尋址資源系統的第一個好處便是:高效的內存管理。
為了大致了解其效果,我們可以把這些代碼:
public class CharacterCustomization : MonoBehaviour { [SerializeField] private List<Material> _armorVariations; [SerializeField] private MeshRenderer _armorRenderer; public void ChangeArmorVariation(int variationId) { _armorRenderer.material = _armorVariations[variationId]; } }
轉化為下面的代碼:
using UnityEngine.AddressableAssets; public class CharacterCustomizationV2 : MonoBehaviour { [SerializeField] private List<AssetReference> _armorVariations; [SerializeField] private MeshRenderer _armorRenderer; public IEnumerator ChangeArmorVariation(int variationId) { var loadProcess = _armorVariations[variationId].LoadAssetAsync(); yield return loadProcess; _armorRenderer.material = loadProcess.Result; } }
轉化后實現的效果如下圖所示,我們可以輕松節省內存使用。
了解使用可尋址資源系統實現更好內存管理的內容,請閱讀:《使用Unity Addressables可尋址資源系統》。
好處2:輕松快捷地加入DLC內容
使用Unity Addressables的第二個好處:可以讓開發者完全控制存儲和加載游戲資源,從而有助於開發者添加和出售可下載內容(DLC)。
即使目前不考慮發布DLC內容,只要在項目中使用Addressables系統,我們就已經提前為這項工作做好了准備。
我們也有其它方法來出售DLC內容,例如:使用Asset Bundles,但這些方法在實現相同作用的同時,會帶來更高的開銷,因此這些方法會逐漸被棄用。維護正常運行的Asset Bundle管線非常消耗時間和精力,需要大量復雜的專業知識。
在Unity中有很多方法可以實現DLC內容,但對於初學者來說,下面代碼是很好的學習起點:
public class DlcManager : MonoBehaviour { // ... public IEnumerator TryDownloadDlc() { if (_hasBoughtDlc && _dlcDownloaded == false) { var operationHandle = Addressables.DownloadDependenciesAsync("DLC-Content"); while (operationHandle.IsDone == false) { _progressText.text = $"{operationHandle.PercentComplete * 100.0f} %"; yield return null; } } } }
通過以上代碼,你應該了解其中的原理。我們能夠使用Unity Addressables,通過少量成本為玩家帶來更多樂趣,何樂而不為?
好處3:減少迭代時間
使用Unity Addressables會減少在多個過程的等待時間。
我們都體驗過按下Unity的Play按鈕后,等待約半分鍾的時間。如果把構建版本部署到移動平台或WebGL平台,那么情況還會更糟。這種等待時間會大幅增加迭代所花的時間。
任何玩家都不喜歡等待,Addressables系統會提供以下幫助:
減少構建大小
游戲往往有很多內容,玩家喜歡體驗內容,而開發者喜歡創作內容,並將把游戲內容提供給玩家。但這並不意味着,我們創作的每個資源都要包含在玩家安裝的構建版本中。實際上,我們要盡可能移除不必要的內容。
玩家都希望盡快開始玩游戲。如果游戲需要2GB的數據流量,以及半小時的下載時間,玩家會對此感到不滿。這樣,玩家可能會更傾向於下載《Candy Crush》這類大小低於50MB的游戲。
其中一種應對策略是:只在安裝程序包含主菜單等運行游戲所需的資源,然后在后台下載剩余游戲內容,首先要下載的是游戲的關卡內容。
這也會使開發期間的部署速度變得更快。我們將能夠每天迭代更多次數,這個好處會在長期時間中累積效果。
減少加載時間
作為游戲開發者和玩家,我們都討厭等待。等待會讓我們失去玩游戲的狀態,我們的游戲時間可能在不經意間就結束了。
Unity正在努力通過改善編輯器和游戲的發布方式,減少玩家開始玩游戲的時間。未來有很多值得期待的功能,例如:Unity 2019.3中避免域重載(domain reloads)的功能很值得期待,但如今它仍處於Beta版。
假設我們正在開發中世紀題材的游戲。數月前,我們為游戲實現了護甲類型。開發過程非常順利,我們生成了超過100MB的游戲內容。
接下來,我們繼續開發其它內容,例如:刀劍對決。我們發現,每次按下Play按鈕測試功能時,都會從已開發功能中加載大量數據,而且加載這些數據也需要大量時間。
按下Play按鈕測試“刀劍對決”的動畫時,由於要加載之前實現的護甲功能,我們會額外等待5秒時間。由於內存帶寬有限,因此加載過程耗費的時間大多發生在I/O過程中。此外,CPU也要對該過程進行處理。
作為開發者,我們會在Unity編輯器中耗費相應的時間。而玩家則要在已發布的游戲中等待更多時間。
了解到這個情況帶來的影響后,我們要使用什么方法解決該問題呢?
Unity Addressables能夠通過兩種方法幫助我們。
1
減少玩家的加載時間
我們可以減少玩家的等待時間。使用資源的間接引用而不是直接引用,這樣會大幅改善加載時間。
通過使用間接引用,即AssetReference,Unity不會同時加載所有內容,而只在必要時加載部分內容。更重要的是,我們可以直接控制加載內容的時間。
2
減少Unity編輯器上的迭代時間
你對Unity Addressables窗口中的Play Mode Script有多少了解呢?Play Mode Script會定義Unity編輯器如何加載標記Addressable的資源。
選中Packed Play Mode,Unity會直接加載預構建的可尋址資源,僅使用少量處理開銷,從而有效減少Unity編輯器中的迭代時間。
使用該功能前,請記得先點擊Build Player Content來構建玩家內容。
我們可以試想一下,把這些方法應用到最急需的內容時會產生怎樣的效果。
小結
本文,我們了解了Unity Addressables能夠幫助進行更好的創作,並給玩家提供更多內容。 我們將從中受益,讓項目在未來數月或來年得到提升。