Unity3D實(shí)現(xiàn)動(dòng)態(tài)加載游戲資源_第1頁(yè)
Unity3D實(shí)現(xiàn)動(dòng)態(tài)加載游戲資源_第2頁(yè)
Unity3D實(shí)現(xiàn)動(dòng)態(tài)加載游戲資源_第3頁(yè)
Unity3D實(shí)現(xiàn)動(dòng)態(tài)加載游戲資源_第4頁(yè)
Unity3D實(shí)現(xiàn)動(dòng)態(tài)加載游戲資源_第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余7頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

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

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

3、意這里并不是下載所有的場(chǎng)景資源。在游戲的過(guò)程中,后臺(tái)繼續(xù)加載資源直到所有加載完畢。一個(gè)簡(jiǎn)單的場(chǎng)景配置文件的例子: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:場(chǎng)景中資源的列表,每一個(gè)資源都對(duì)應(yīng)一個(gè) unity3DName:gameobject 的名字,一個(gè)場(chǎng)景中不應(yīng)該重名Source:資源的物理路徑及文件名Position:ga

5、meobject 的坐標(biāo)的 gameobjectScenes/MyDemoSence.txt。然后注冊(cè) MainMonoBehavior的 update 事件。你會(huì)注意到 WritingTable 里面包含了 Lamp,這兩個(gè)對(duì)象是父子的關(guān)系。配置文件應(yīng)該是由程序生成的,手工也可以修改。另外在游戲上線后,客戶端接收到的配置文件應(yīng)該是加密并壓縮過(guò)的。主程序: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#的事件機(jī)制,大家可以看看我以前翻譯過(guò)的國(guó)外一個(gè)牛人的文章:C#事件和 Un

7、ity3D在 start 方法里調(diào)用 ResourceManager,先加載配置文件。每一次調(diào)用 update 方法,MainMonoBehavior 會(huì)把 update 事件分發(fā)給ResourceManager,因?yàn)?ResourceManager 注冊(cè)了 MainMonoBehavior 的 update 事件。在 LoadSence 方法里先創(chuàng)建一個(gè) Asset 的對(duì)象,這個(gè)對(duì)象是對(duì)應(yīng)于配置文件的,設(shè)置 type 是 Json,source 是傳進(jìn)來(lái)的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)建一個(gè) Asset 的對(duì)象,這個(gè)對(duì)象是對(duì)應(yīng)于配置文件的,設(shè)置 type 是 Json,source 是傳進(jìn)來(lái)的“Scenes/MyDemoSence.txt”。然后注冊(cè) 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 加載配置文件對(duì)象及所有資源對(duì)象。每一幀都要判斷是否加載結(jié)束,如果結(jié)束清空 mScene 和 mSceneAsset對(duì)象為下一次加載做準(zhǔn)備,并且取消 update 事件的注冊(cè)。最核心的 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);)傳進(jìn)來(lái)的是要加載的資源對(duì)象,先得到它的物理地址,mResourcePath 是個(gè)全局變量保存資源服務(wù)器的網(wǎng)址,得到 fullFi

12、leName 類似http:/ wwwCacheMap 判斷資源是否已經(jīng)加載完畢,如果加載完畢把加載好的 www 對(duì)象放到 Map 里緩存起來(lái)。看看前面 Json 配置文件,Chair1 和 Chair2 用到了同一個(gè)資源 Chair001.unity3d,加載 Chair2 的null 等到下一幀再做判斷。這就是 WWW 類的特點(diǎn),剛開始用 WWW 下載資源的時(shí)候是不能馬上使用的,要等待諾干幀下載完成以后才可以使用??梢杂?yield 返回 www,這樣代碼簡(jiǎn)單,但是 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);時(shí)候就不需要下載了。如果當(dāng)前幀沒(méi)有加載完畢,返回/loadsceneforeach(AssetsceneAssetinmScene.AssetList)if(sceneAsset.isLoadFinished)continue;elseLoadAsset(sceneAsset);if(!sceneAsset.isLoadFinished)return

14、null;代碼能夠運(yùn)行到這里,說(shuō)明資源都已經(jīng)下載完畢了?,F(xiàn)在開始加載處理資源了。第一次肯定是先加載配置文件,因?yàn)槭?Json 格式,用 JsonMapper類把它轉(zhuǎn)換成 C#對(duì)象,我用的是 LitJson 開源類庫(kù)。然后循環(huán)遞歸處理場(chǎng)景中的每一個(gè)資源。如果沒(méi)有完成,返回 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 對(duì)象,調(diào)用 Instantiate 方法實(shí)傷 J 化成 Unity3D 的 gameobject。UpdateGameObject 方法設(shè)置 gameobject 各個(gè)屬性,如位置和旋轉(zhuǎn)角度。然后又是一個(gè)循環(huán)遞歸為了加載子對(duì)象,處理 gameobject 的父子關(guān)系。注意如果 LoadAsset返回 null,說(shuō)明 www 沒(méi)有下載完畢,等到下一幀處理。最后設(shè)置加載完成標(biāo)志

17、返回 asset 對(duì)象。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;這里只設(shè)置了 gameobject 的 3 個(gè)屬性,眼力好的同學(xué)一定會(huì)發(fā)現(xiàn)這些對(duì)象都是死的”,因?yàn)樯倭四_本屬性,它們不會(huì)和玩家交互。設(shè)置腳本屬性要復(fù)雜的多,編譯好的腳本隨著主程序下載到本地,它們也應(yīng)該通過(guò)配置文件加載,再通過(guò) C#的反射創(chuàng)建腳本對(duì)象,賦給相應(yīng)的 gameobject最后是 Scene 和 asset 代碼:publicclassScenepublicListAssetListget;set;publicclassAssetpublicconstbyteTYPE_JSON=1;終于開始處理真正的資源了,從緩存中找到publicconstby

溫馨提示

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

評(píng)論

0/150

提交評(píng)論