Unity游戏开发——新发教你做游戏(三):3种资源加载方式
文章目錄
- 一、前言
- 二、Unity的目錄結構規范
- 1、Resources(不是很推薦把資源放這個目錄)
- 2、RawAssets(存放生資源)
- 3、GameRes(存放熟資源)
- 4、StreamingAssets(存放AssetBundle)
- 5、其他目錄
- 5.1、Editor目錄(存放編輯器的擴展腳本)
- 5.2、Scripts目錄 (存放腳本)
- 5.3、Scenes目錄 (存放場景)
- 5.4、Plugins目錄(SDK依賴的庫文件)
- 5.5、Shaders目錄(存放shader腳本)
- 三、3種資源加載方式
- 1、編輯器環境下加載GameRes目錄中的資源
- 2、加載Resources目錄中的資源
- 3、移動平臺加載StreamingAssets目錄中的資源
- 3.1、設置資源的AssetBundle名
- 3.2、AssetBundle打包
- 3.3、AssetBundle加載
- 四、資源熱更
一、前言
文章列表
Unity游戲開發——新發教你做游戲(一):打開游戲開發新世界的大門
Unity游戲開發——新發教你做游戲(二):60個Unity免費資源獲取網站
Unity游戲開發——新發教你做游戲(三):3種資源加載方式
Unity游戲開發——新發教你做游戲(四):角色移動控制
Unity游戲開發——新發教你做游戲(五):導航系統Navigation
Unity游戲開發——新發教你做游戲(六):教你2個步驟實現搖桿功能
Unity游戲開發——新發教你做游戲(七):Animator控制角色動畫播放
本工程Demo我已上傳到GitHub,感興趣的同學可以下載下來學習。
GitHub工程地址:https://github.com/linxinfa/Unity-RpgGameDemo
嗨,大家好,我是新發,上一篇文章我們講了資源的獲取,我們有了美術資源之后,導入Unity中,就需要通過程序來加載和管理資源,本文我將介紹資源加載的三種方式。
二、Unity的目錄結構規范
第一個問題,我們的資源放在什么目錄中?那么,就需要先知道Unity的目錄結構。
Assets為主目錄,其他所有文件都在Assets目錄下,如下,這是我的目錄結構,也建議大家在創建工程時就養成規范目錄的習慣,不然項目后期必定返工整理目錄和文件規范。
以上,和游戲資源相關的目錄是四個:Resources、RawAssets、GameRes、StreamingAssets。
關于Unity的目錄文件操作,我之前寫過一篇文章:https://blog.csdn.net/linxinfa/article/details/51679528
為了方便理清關系,我畫了下面這個圖。
1、Resources(不是很推薦把資源放這個目錄)
只讀文件;資源全部被無條件被打進包內;這個文件夾下的資源將被加密和壓縮打包;通過Resoureces.Load方式加載。
做Demo演示,可以直接把資源放這個目錄,如果是實戰項目,建議將資源打成AssetBundle放在StreamingAssets目錄或服務器中,方便熱更資源。
2、RawAssets(存放生資源)
RawAssets不是Unity默認的文件夾,所以文件夾名字沒有嚴格要求一定要叫RawAssets。
什么是生資源呢?生就是未加工的意思,大家應該聽過生肉、熟肉,嘿嘿。
生資源,比如一個角色模型,我們一般是包裝成預設,一個成品預設。這個預設依賴了網格、動畫、材質球和貼圖等資源,這些被成品依賴的零件就是生資源。
RawAssets中的生資源,被依賴性得打進包內,比如,成品預設放在Resources目錄中,那么成品依賴的對應的生資源就會被打進包內了,當然,如果沒有被任何成品預設依賴,那么對應的生資源就不會被打進包內了。
3、GameRes(存放熟資源)
相對應與生資源,我們加工好的成品資源就是熟資源。在Editor環境下,直接通過AssetDatabase.LoadAssetAtPah同步加載資源。發布的時候,我們將GameRes中的資源打成AssetBundle放到StreamingAssets目錄中,當需要資源熱更的時候,我們將新打的AssetBundle放到遠程服務器上,客戶端下載到本地的Application.persistentDataPath沙箱目錄,再通過AssetBundle.LoadFromFile同步加載。
加載資源的時候,優先去Application.persistentDataPath中找,如果沒有才去StreamingAssets中找。
4、StreamingAssets(存放AssetBundle)
StreamingAssets文件夾是一個只讀的文件夾,但是它和Resources有點區別,Resources文件夾下的資源會進行一次壓縮,而且也會加密,不使用點特殊辦法是拿不到原始資源的。但是StreamingAssets文件夾就下面的所有資源不會被加密,是原封不動的打包到發布包中,這樣很容易就拿到里面的文件。我們打AssetBundle的時候建議自己做一次加密。
我們可以通過WWW或UnityWebRequest異步加載資源,也可以通過AssetBundle.LoadFromFile同步加載資源。
5、其他目錄
5.1、Editor目錄(存放編輯器的擴展腳本)
所有資源文件或者腳本文件都不會被打進發布包中,并且腳本也只能在編輯時使用。
工具類的腳本放在這里,或者是一些編輯時用的DLL。
5.2、Scripts目錄 (存放腳本)
我們的c#游戲腳本放在這個目錄中,注意,如果是編輯器工具類的c#腳本,則放在Editor目錄中。
5.3、Scenes目錄 (存放場景)
我們的場景文件放在這個目錄中,包括場景的Lighting燈光烘焙數據、Navigation導航數據等。
5.4、Plugins目錄(SDK依賴的庫文件)
項目中很可能需要接一些第三方SDK,比如微信開放平臺的SDK,對應的SDK庫文件就是放這個目錄中(子目錄Plugins/Android和Plugins/iOS)。還有你可能會用到一些第三方庫,比如HoTween.dll、Zxing.dll、Ionic.Zip.Unity.dll等,都是放在Plugins中。
5.5、Shaders目錄(存放shader腳本)
shader一般是技術美術來寫。Unity2018推出了ShaderGraph,我之前寫了一篇關于ShaderGraph的實戰文章,大家有興趣可以看看:https://blog.csdn.net/linxinfa/article/details/108049048
三、3種資源加載方式
1、編輯器環境下加載GameRes目錄中的資源
在編輯器環境下,直接使用這種方式加載資源。
比如加載Assets/GameRes/Cube.prefab。
注意,這種方式只能在編輯器環境下使用。
2、加載Resources目錄中的資源
Resources目錄中的資源,通過Resources.Load同步加載。
比如加載Assets/Resources/Cube.prefab。
3、移動平臺加載StreamingAssets目錄中的資源
一般我們是將GameRes目錄中的資源打成AssetBundle放在StreamingAssets目錄中,然后通過WWW或UnityWebRequest異步加載,或者通過AssetBundle.LoadFromFile同步加載。
3.1、設置資源的AssetBundle名
首先,對資源設置AssetBunle名稱,建議以所在目錄為名稱,比如下圖中的Cube和Sphere兩個預設,都設置成3dprefabs。
如果資源比較多,建議寫個Editor工具執行自動化設置。
3.2、AssetBundle打包
接著,通過BuildPipeline.BuildAssetBundles進行AssetBundle打包。
using UnityEngine; using UnityEditor; using System.IO;public class BuildTools {[MenuItem("Tools/BuildAB")]public static void StartBuildAB(){// 第3個參數根據你的平臺而定BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows);AssetDatabase.Refresh();} }打AssetBundle成功,即可在StreamingAssets目錄中看到了
3.3、AssetBundle加載
接下來是游戲運行時加載AssetBundle,比如我們想加載3dprefabs這個AssetBundle中的Cube。
方法一:AssetBundle.LoadFromFile同步加載(推薦)
方法二:UnityWebRequest異步加載(支持服務器上在資源加載)
IEnumerator LoadAsset() {//注意:本地目錄需要加上"file://"string uri = "file://" + Application.streamingAssetsPath + "/3dprefabs";UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri, 0);yield return request.SendWebRequest();if (request.isNetworkError){Debug.LogError(request.error);}//獲取到ab包AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);//加載AssetGameObject prefab = ab.LoadAsset<GameObject>("Cube");//實例化GameObject go = Instantiate<GameObject>(prefab); }方法三:WWW異步加載(支持服務器上在資源加載,已過時)
IEnumerator LoadAsset() {//注意:本地目錄需要加上"file://"string uri = "file://" + Application.streamingAssetsPath + "/3dprefabs";WWW www = new WWW(uri);yield return www;//獲取到ab包AssetBundle ab = www.assetBundle;//加載AssetGameObject prefab = ab.LoadAsset<GameObject>("Cube");//實例化GameObject go = Instantiate<GameObject>(prefab); }四、資源熱更
項目上線后,很可能需要熱更游戲資源,這個時候,就需要從服務器端下載AssetBundle到本地目錄:Application.persistentDataPath。
關于如何下載文件,參見我之前這篇文章:
https://blog.csdn.net/linxinfa/article/details/94436027
加載資源的時候,優先去Application.persistentDataPath找看看有沒有對應的資源,如果有,已Application.persistentDataPath中的資源為準,否則,再去Application.streamingAssets目錄中找資源。
//你的資源文件 string resName = System.IO.Path.Combine(Application.persistentDataPath, "你的資源文件名"); if(System.IO.File.Exists(resName)) {//在Application.persistentDataPath目錄中加載資源 } else {//在Application.streamingAssets目錄中加載資源 }也有一些人是在游戲首次啟動時將Application.streamingAssets目錄中的所有AssetBundle拷貝到Application.persistentDataPath目錄中,后面如果有資源熱更,就會覆蓋Application.persistentDataPath目錄中的資源,加載資源統一在Application.persistentDataPath中找。
總結
以上是生活随笔為你收集整理的Unity游戏开发——新发教你做游戏(三):3种资源加载方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阈值法进行边缘检测matlab
- 下一篇: android 手势识别代码