Unity3D實現(xiàn)動態(tài)加載游戲資源_第1頁
Unity3D實現(xiàn)動態(tài)加載游戲資源_第2頁
Unity3D實現(xiàn)動態(tài)加載游戲資源_第3頁
Unity3D實現(xiàn)動態(tài)加載游戲資源_第4頁
Unity3D實現(xiàn)動態(tài)加載游戲資源_第5頁
免費預覽已結束,剩余7頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、Unity3D 實現(xiàn)動態(tài)加載游戲資源在 flash 時代,資源的動態(tài)加載非常的普遍,主要是受限于網(wǎng)速的快慢,我們在用 unity3d 制作在線項目的時候,不可避免的要考慮到優(yōu)化加載的問題,這篇文章算是比較好的經(jīng)驗之談了,轉(zhuǎn)來大家看看!用 Unity3D 制作基于 web 的網(wǎng)絡游戲,不可避免的會用到一個技術-資源動態(tài)加載。比如想加載一個大場景的資源,不應該在游戲的開始讓用戶長時間等待全部資源的加載完畢。應該優(yōu)先加載用戶附近的場景資源,在游戲的過程中,不影響操作的情況下,后臺加載剩余的資源,直到所有加載完畢。本文包含一些代碼片段講述實現(xiàn)這個技術的一種方法。本方法不一定是最好的,希望能拋磚引玉。代

2、碼是 C#寫的,用到了 Json,還有 C#的事件機制。在講述代碼之前,先想象這樣一個網(wǎng)絡游戲的開發(fā)流程。首先美工制作場景資源的 3D 建模,游戲設計人員把 3D 建模導進 Unity3D,托托拽拽編輯場景,完成后把每個 gameobject 導出成 XXX.unity3d 格式的資源文件(參看 BuildPipeline),并且把整個場景的信息生成一個配置文件,xml 或者 Json 格式(本文使用 Json)。最后還要把資源文件和場景配置文件上傳到服務器,最好使用 CMS 管理??蛻舳诉\行游戲時,先讀取服務器的場景配置文件,再根據(jù)玩家的位置從服務器下載相應的資源文件并加載,然后開始游戲,注

3、意這里并不是下載所有的場景資源。在游戲的過程中,后臺繼續(xù)加載資源直到所有加載完畢。一個簡單的場景配置文件的例子:MyDemoSence.txtJson 代碼:AssetList:Name:Chair1,Source:Prefabs/Chair001.unity3d,Position:2,0,-5,Rotation:0.0,60.0,0.0,Name:Chair2,Source:Prefabs/Chair001.unity3d,Position:1,0,-5,).(Name:Vanity,Source:Prefabs/vanity001.unity3d,Position:0,0,-4,Rotat

4、ion:0.0,0.0,0.0),(Name:WritingTable,Source:Prefabs/writingTable001.unity3d,Position:0,0,-7,Rotation:0.0,0.0,0.0,AssetList:Name:Lamp,Source:Prefabs/lamp001.unity3d,Position:-0.5,0.7,-7,Rotation:0.0,0.0,0.0AssetList:場景中資源的列表,每一個資源都對應一個 unity3DName:gameobject 的名字,一個場景中不應該重名Source:資源的物理路徑及文件名Position:ga

5、meobject 的坐標的 gameobjectScenes/MyDemoSence.txt。然后注冊 MainMonoBehavior的 update 事件。你會注意到 WritingTable 里面包含了 Lamp,這兩個對象是父子的關系。配置文件應該是由程序生成的,手工也可以修改。另外在游戲上線后,客戶端接收到的配置文件應該是加密并壓縮過的。主程序:C#代碼publicclassMainMonoBehavior:MonoBehaviourpublicdelegatevoidMainEventHandler(GameObjectdispatcher);publiceventMainEven

6、tHandlerStartEvent;publiceventMainEventHandlerUpdateEvent;publicvoidStart()ResourceManager.getInstance().LoadSence(Scenes/MyDemoSence.txt);if(StartEvent!=null)StartEvent(this.gameObject);publicvoidUpdate。if(UpdateEvent!=null)UpdateEvent(this.gameObject);這里面用到了 C#的事件機制,大家可以看看我以前翻譯過的國外一個牛人的文章:C#事件和 Un

7、ity3D在 start 方法里調(diào)用 ResourceManager,先加載配置文件。每一次調(diào)用 update 方法,MainMonoBehavior 會把 update 事件分發(fā)給ResourceManager,因為 ResourceManager 注冊了 MainMonoBehavior 的 update 事件。在 LoadSence 方法里先創(chuàng)建一個 Asset 的對象,這個對象是對應于配置文件的,設置 type 是 Json,source 是傳進來的ResourceManager.csprivateMainMonoBehaviormainMonoBehavior;privatestri

8、ngmResourcePath;privateScenemScene;privateAssetmSceneAsset;privateResourceManager()mainMonoBehavior=GameObject.Find(MainCamera).GetComponent();mResourcePath=PathUtil.getResourcePath();publicvoidLoadSence(stringfileName)mSceneAsset=newAsset();mSceneAsset.Type=Asset.TYPE_JSON;mSceneAsset.Source=fileNa

9、me;mainMonoBehavior.UpdateEvent+=OnUpdate;在 LoadSence 方法里先創(chuàng)建一個 Asset 的對象,這個對象是對應于配置文件的,設置 type 是 Json,source 是傳進來的“Scenes/MyDemoSence.txt”。然后注冊 MainMonoBehavior 的 update 事件。publicvoidOnUpdate(GameObjectdispatcher)if(mSceneAsset!=null)LoadAsset(mSceneAsset);if(!mSceneAsset.isLoadFinished)return;/clea

10、rmSceneandmSceneAssetfornextLoadSencecallmScene=null;mSceneAsset=null;)mainMonoBehavior.UpdateEvent-二 OnUpdate;)OnUpdate 方法里調(diào)用 LoadAsset 加載配置文件對象及所有資源對象。每一幀都要判斷是否加載結束,如果結束清空 mScene 和 mSceneAsset對象為下一次加載做準備,并且取消 update 事件的注冊。最核心的 LoadAsset 方法:privateAssetLoadAsset(Assetasset)stringfullFileName=mResou

11、rcePath+/+asset.Source;/ifwwwresourceisnew,setintowwwcacheif(!wwwCacheMap.ContainsKey(fullFileName)if(asset.www=二 null)asset.www=newWWW(fullFileName);returnnull;)if(!asset.www.isDone)returnnull;)wwwCacheMap.Add(fullFileName,asset.www);)傳進來的是要加載的資源對象,先得到它的物理地址,mResourcePath 是個全局變量保存資源服務器的網(wǎng)址,得到 fullFi

12、leName 類似http:/ wwwCacheMap 判斷資源是否已經(jīng)加載完畢,如果加載完畢把加載好的 www 對象放到 Map 里緩存起來??纯辞懊?Json 配置文件,Chair1 和 Chair2 用到了同一個資源 Chair001.unity3d,加載 Chair2 的null 等到下一幀再做判斷。這就是 WWW 類的特點,剛開始用 WWW 下載資源的時候是不能馬上使用的,要等待諾干幀下載完成以后才可以使用??梢杂?yield 返回 www,這樣代碼簡單,但是 C#要求調(diào)用 yield 的方法返回 lEnumerator類型,這樣限制太多不靈活。繼續(xù) LoadAsset 方法:if(

13、asset.Type 二二 Asset.TYPE_JSON)/Jsonif(mScene 二二 null)stringjsonTxt=mSceneAsset.www.text;mScene=JsonMapper.ToObject(jsonTxt);時候就不需要下載了。如果當前幀沒有加載完畢,返回/loadsceneforeach(AssetsceneAssetinmScene.AssetList)if(sceneAsset.isLoadFinished)continue;elseLoadAsset(sceneAsset);if(!sceneAsset.isLoadFinished)return

14、null;代碼能夠運行到這里,說明資源都已經(jīng)下載完畢了?,F(xiàn)在開始加載處理資源了。第一次肯定是先加載配置文件,因為是 Json 格式,用 JsonMapper類把它轉(zhuǎn)換成 C#對象,我用的是 LitJson 開源類庫。然后循環(huán)遞歸處理場景中的每一個資源。如果沒有完成,返回 null,等待下一幀處理。繼續(xù) LoadAsset 方法:elseif(asset.Type=Asset.TYPE_GAMEOBJECT)/Gameobjectif(asset.gameObject=null)wwwCacheMapfullFileName.assetBundle.LoadAll();GameObjectgo=

15、(GameObject)GameObject.Instantiate(wwwCacheMapfullFileName.assetBundle.mainAsset);UpdateGameObject(go,asset);asset.gameObject=go;if(asset.AssetList!=null)foreach(AssetassetChildinasset.AssetList)if(assetChild.isLoadFinished)continue;elseAssetassetRet=LoadAsset(assetChild);if(assetRet!=null)assetRet.

16、gameObject.transform.parent=asset.gameObject.transform;elsereturnnull;asset.isLoadFinished=true;returnasset;www 對象,調(diào)用 Instantiate 方法實傷 J 化成 Unity3D 的 gameobject。UpdateGameObject 方法設置 gameobject 各個屬性,如位置和旋轉(zhuǎn)角度。然后又是一個循環(huán)遞歸為了加載子對象,處理 gameobject 的父子關系。注意如果 LoadAsset返回 null,說明 www 沒有下載完畢,等到下一幀處理。最后設置加載完成標志

17、返回 asset 對象。UpdateGameObject 方法:privatevoidUpdateGameObject(GameObjectgo,Assetasset)/=asset.Name;/positionVector3vector3=newVector3(float)asset.Position0,(float)asset.Position1,(float)asset.Position2);go.transform.position=vector3;/rotationvector3=newVector3(float)asset.Rotation0,(float)a

18、sset.Rotation1,(float)asset.Rotation2);go.transform.eulerAngles=vector3;這里只設置了 gameobject 的 3 個屬性,眼力好的同學一定會發(fā)現(xiàn)這些對象都是死的”,因為少了腳本屬性,它們不會和玩家交互。設置腳本屬性要復雜的多,編譯好的腳本隨著主程序下載到本地,它們也應該通過配置文件加載,再通過 C#的反射創(chuàng)建腳本對象,賦給相應的 gameobject最后是 Scene 和 asset 代碼:publicclassScenepublicListAssetListget;set;publicclassAssetpublicconstbyteTYPE_JSON=1;終于開始處理真正的資源了,從緩存中找到publicconstby

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論