




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Unity3D 实现动态加载游戏资源在 flash 时代,资源的动态加载非常的普遍,主要是受限于网速的快慢,我们在用 unity3d 制作在线项目的时候,不可避免的要考虑到优化加载的问题,这篇文章算是比较好的经验之谈了,转来大家看看!用 Unity3D 制作基于 web 的网络游戏,不可避免的会用到一个技术-资源动态加载。比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完毕。应该优先加载用户附近的场景资源,在游戏的过程中,不影响操作的情况下,后台加载剩余的资源,直到所有加载完毕。本文包含一些代码片段讲述实现这个技术的一种方法。本方法不一定是最好的,希望能抛砖引玉。代
2、码是 C#写的,用到了 Json,还有 C#的事件机制。在讲述代码之前,先想象这样一个网络游戏的开发流程。首先美工制作场景资源的 3D 建模,游戏设计人员把 3D 建模导进 Unity3D,托托拽拽编辑场景,完成后把每个 gameobject 导出成 XXX.unity3d 格式的资源文件(参看 BuildPipeline),并且把整个场景的信息生成一个配置文件,xml 或者 Json 格式(本文使用 Json)。最后还要把资源文件和场景配置文件上传到服务器,最好使用 CMS 管理。客户端运行游戏时,先读取服务器的场景配置文件,再根据玩家的位置从服务器下载相应的资源文件并加载,然后开始游戏,注
3、意这里并不是下载所有的场景资源。在游戏的过程中,后台继续加载资源直到所有加载完毕。一个简单的场景配置文件的例子: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 方法里调用 ResourceManager,先加载配置文件。每一次调用 update 方法,MainMonoBehavior 会把 update 事件分发给ResourceManager,因为 ResourceManager 注册了 MainMonoBehavior 的 update 事件。在 LoadSence 方法里先创建一个 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 方法里先创建一个 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 方法里调用 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 是个全局变量保存资源服务器的网址,得到 fullFi
12、leName 类似http:/ wwwCacheMap 判断资源是否已经加载完毕,如果加载完毕把加载好的 www 对象放到 Map 里缓存起来。看看前面 Json 配置文件,Chair1 和 Chair2 用到了同一个资源 Chair001.unity3d,加载 Chair2 的null 等到下一帧再做判断。这就是 WWW 类的特点,刚开始用 WWW 下载资源的时候是不能马上使用的,要等待诺干帧下载完成以后才可以使用。可以用 yield 返回 www,这样代码简单,但是 C#要求调用 yield 的方法返回 lEnumerator类型,这样限制太多不灵活。继续 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;代码能够运行到这里,说明资源都已经下载完毕了。现在开始加载处理资源了。第一次肯定是先加载配置文件,因为是 Json 格式,用 JsonMapper类把它转换成 C#对象,我用的是 LitJson 开源类库。然后循环递归处理场景中的每一个资源。如果没有完成,返回 null,等待下一帧处理。继续 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 对象,调用 Instantiate 方法实伤 J 化成 Unity3D 的 gameobject。UpdateGameObject 方法设置 gameobject 各个属性,如位置和旋转角度。然后又是一个循环递归为了加载子对象,处理 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 个属性,眼力好的同学一定会发现这些对象都是死的”,因为少了脚本属性,它们不会和玩家交互。设置脚本属性要复杂的多,编译好的脚本随着主程序下载到本地,它们也应该通过配置文件加载,再通过 C#的反射创建脚本对象,赋给相应的 gameobject最后是 Scene 和 asset 代码:publicclassScenepublicListAssetListget;set;publicclassAssetpublicconstbyteTYPE_JSON=1;终于开始处理真正的资源了,从缓存中找到publicconstby
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030年中国陶瓷纤维市场竞争格局与前景发展策略分析报告
- 2025-2030年中国造纸机械市场运行态势及投资战略研究报告
- 2025-2030年中国蚝肉行业发展状况及营销战略研究报告
- 2025-2030年中国矿渣粉产业十三五规划及发展策略分析报告
- 2025-2030年中国电子铜箔市场运行状况及发展趋势预测报告
- 江西洪州职业学院《经济学的思维方式》2023-2024学年第二学期期末试卷
- 沈阳职业技术学院《受众与视听率分析》2023-2024学年第二学期期末试卷
- 益阳职业技术学院《公共关系》2023-2024学年第二学期期末试卷
- 2025届上海市松江区届高三上学期一模考试历史试卷
- 辽宁中医药大学杏林学院《软件测试技术实验》2023-2024学年第二学期期末试卷
- GB/T 44828-2024葡萄糖氧化酶活性检测方法
- GB/T 44865-2024物联网基于物联网和传感网技术的动产监管集成平台系统要求
- 燃气公司绩效考核管理制度
- 高中生物课程标准(人教版)
- 第三章-自然语言的处理(共152张课件)
- 2023版初中语文新课程标准
- 2024至2030年中国蜜柚行业市场发展现状及潜力分析研究报告
- 人音版音乐一年级上册第3课《国旗国旗真美丽》说课稿
- GB/T 44255-2024土方机械纯电动液压挖掘机能量消耗量试验方法
- DL∕T 1785-2017 电力设备X射线数字成像检测技术导则
- 山东财经大学《大学英语》2022-2023学年期末试卷
评论
0/150
提交评论