Unity3D教程:Json实现资源动态加载

上传人:m**** 文档编号:159059497 上传时间:2022-10-08 格式:DOCX 页数:15 大小:52.24KB
收藏 版权申诉 举报 下载
Unity3D教程:Json实现资源动态加载_第1页
第1页 / 共15页
Unity3D教程:Json实现资源动态加载_第2页
第2页 / 共15页
Unity3D教程:Json实现资源动态加载_第3页
第3页 / 共15页
资源描述:

《Unity3D教程:Json实现资源动态加载》由会员分享,可在线阅读,更多相关《Unity3D教程:Json实现资源动态加载(15页珍藏版)》请在装配图网上搜索。

1、Unity3D 教程: Json实现资源动态加载 Posted on 2013 年06月05日by U3d / Unity3D 基础教程/被围观142次 用Unity3D制作基于web的网络游戏,不可避免的会用到一个技术-资源动态加载。 比如想加载一个大场景的资源,不应该在游戏的开始让用户长时间等待全部资源的加载完 毕。应该优先加载用户附近的场景资源,在游戏的过程中,不影响操作的情况下,后台加 载剩余的资源,直到所有加载完毕。 本文包含一些代码片段讲述实现这个技术的一种方法。本方法不一定是最好的,希望 能抛砖引玉。代码是C#写的,用到了 Json,还有C#的事件机制。 在讲述代码之前,

2、先想象这样一个网络游戏的开发流程。首先美工制作场景资源的 3D建模,游戏设计人员把3D建模导进Unity3D,托托拽拽编辑场景,完成后把每个 gameobject导出成XXX.unity3d格式的资源文件(参看BuildPipeline ),并且把整个 场景的信息生成一个配置文件,xml或者Json格式(本文使用Json )。最后还要把资源 文件和场景配置文件上传到服务器,最好使用CMS管理。客户端运行游戏时,先读取服 务器的场景配置文件,再根据玩家的位置从服务器下载相应的资源文件并加载,然后开始 游戏,注意这里并不是下载所有的场景资源。在游戏的过程中,后台继续加载资源直到所 有加载完毕。

3、 一个简单的场景配置文件的例子: MyDemoSe nce.txt Json代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 4 6 47 48 49 “AssetList" : [{ “Name" : “Chair 1", Source" : 、'Prefabs/

4、Chair001.unity3d", ''Position" : [2,0,-5], ''Rotation" : [0.0,60.0,0.0] “Name" : “Chair 2", Source" : “Prefabs/Chair001.unity3d", Position" : [1,0,-5], ''Rotation" : [0.0,0.0,0.0] }, ''Name" : “Vanity", Source" : “Prefabs/vanity001.unity3d", ''Position" : [0,0,-4], “Rotation" : [0.0,0.0,0

5、.0] “Name" : 'Writing Table", Source" : “Prefabs/writingTable001.unity3d 'Position" : [0,0,-7], 'Rotation" : [0.0,0.0,0.0], 50 51 52 53 54 55 56 57 58 59 60 61 62 63 “

6、Name” : “Lamp”, Source” : “Prefabs/lampOOl.unity3d”, “Position” : [—0.5,0・7,—7], “Rotation” : [0.0,0.0,0.0] AssetList :场景中资源的列表,每一个资源都对应一个unity3D的gameobject Name : gameobject的名字,一个场景中不应该重名 Source :资源的物理路径及文件名 Position : gameobject 的坐标 Rotation : gameobject 的旋转角度

7、你会注意到Writing Table里面包含了 Lamp,这两个对象是父子的关系。配置文件 应该是由程序生成的,手工也可以修改。另外在游戏上线后,客户端接收到的配置文件应 该是加密并压缩过的。 主程序: C#代码 01 02 public class MainMonoBehavior : MonoBehaviour { 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 pub

8、lic delegate void MainEventHandler(GameObject dispatcher); public event MainEventHandler StartEvent; public event MainEventHandler UpdateEvent; public void Start() { ResourceManaqer.getInstance().LoadSence(“Scenes/MyDemoSence.txt”); if(StartEvent != null){ StartEvent(this.qameObject); public

9、void Update() { if (UpdateEvent != null) { UpdateEvent(this.qameObject); 这里面用到了 c#的事件机制,大家可以看看我以前翻译过的国外一个牛人的文章。C#事 件和 Unity3D 在start方法里调用ResourceManager,先加载配置文件。每一次调用update方 法,Mai nMon oBehavior 会把 update 事件分发给 ResourceMa nager,因为 ResourceManager注册了 MainMonoBehavior 的 update 事件。 ResourceMa

10、nager.cs C#代码 01 02 03 private MainMonoBehavior mainMonoBehavior; 04 05 06 07 08 09 10 private Scene mScene; private Asset mSceneAsset; private ResourceManager() { 11 mainMonoBehavior = GameObject.Find(“Main Camera”).GetComponent

11、thUtil・ qetResourcePath(); 15 16 17 public void LoadSence(string fileName) { 18 19 mSceneAsset = new Asset(); 20 21 mSceneAsset.Type = Asset.TYPE JSON; 22 23 24 mSceneAsset ・ Source fileName; private string mResourcePath; 25 mainMonoBehavior.UpdateEvent += OnUpdate; 26 27 在LoadS

12、enee方法里先创建一个Asset的对象,这个对象是对应于配置文件的,设 置 type 是 Json,source 是传进来的 “Seenes/MyDemoSence.txt”。然后注册 MainMonoBehavior 的 update 事件。 C#代码 01 02 03 04 05 06 07 08 09 public void OnUpdate(GameObject dispatcher) { if (mSceneAsset != null) { LoadAsset(mSceneAsset); if (!mSceneAsset.isLoadFinished)

13、{ return; 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 } //clear mScene and mSceneAsset for next LoadSence call mScene = null; mSceneAsset = null; } mainMonoBehavior.UpdateEvent -= OnUpdate; } On Update方法里调用LoadAsset加载配置文件对象及所有资源对象。每一帧都要判断 是否加载结束,如果结束清空mScene和mSceneAsset对象为

14、下一次加载做准备,并且 取消update事件的注册。 最核心的LoadAsset方法: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 private Asset LoadAsset(Asset asset) { string fullFileName = mResourcePath + “/” + asset ・ Source; //if www resource is new, set into www cache if (!wwwCacheMap.ContainsKe

15、y(fullFileName)) { if (asset.www == null asset.www = new WWW(fullFileName); return null; if (!asset.www.isDone) { return null; C#代码 22 23 wwwCacheMap.Add(fullFileName, asset.www); 24 25 26 传进来的是要加载的资源对象,先得到它的物理地址,mResourcePath是个全局变量保 存资源服务器的网址,得到fullFileName类似 http://www.mydemogame.eom/

16、asset/Prefabs/xxx.u ni ty3d。然后通过 wwwCacheMap判断资源是否已经加载完毕,如果加载完毕把加载好的www对象放到 Map里缓存起来。看看前面Json配置文件,Chair 1和Chair 2用到了同一个资源 ChairOOl.unity3d,加载Chair 2的时候就不需要下载了。如果当前帧没有加载完毕,返 回null等到下一帧再做判断。这就是WWW类的特点,刚开始用WWW下载资源的时候 是不能马上使用的,要等待诺干帧下载完成以后才可以使用。可以用yield返回www,这 样代码简单,但是C#要求调用yield的方法返回IEnumerator类型,这样限制太

17、多不灵 活。 继续LoadAsset方法: 01 02 03 04 05 06 07 08 09 Lf (asset.Type if (mScene Asset.TYPE JSON) { //Json null) { string jsonTxt = mSceneAsset ・ www.text; mScene = JsonMapper.ToObject(jsonTxt); C#代码 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3

18、0 31 32 33 //load scene foreach (Asset sceneAsset in mScene.AssetList) { if (sceneAsset.isLoadFinished) { continue; } else { LoadAsset(sceneAsset); if (!sceneAsset.isLoadFinished) { return null; 代码能够运行到这里,说明资源都已经下载完毕了。现在开始加载处理资源了。第一 次肯定是先加载配置文件,因为是Js on格式,用Js on Mapper类把它转换成C#对象,我 用的是L

19、itJson开源类库。然后循环递归处理场景中的每一个资源。如果没有完成,返回 null,等待下一帧处理。 继续LoadAsset方法: C#代码 0 else if (asset.Type == Asset.TYPE GAMEOBJECT) { //Gameobject 1 0 2 0 if (asset.gameObject == null) { 3 0 4 0 wwwCacheMap[fullFileName].assetBundle.LoadAll(); 5 0 6 0 7 GameObject go =

20、 (GameObject)GameObject.Instantiate(wwwCacheMap[fullFileName].assetBundle.m ainAsset); 0 8 0 UpdateGameObject(go, asset); 9 1 0 1 asset.gameObject = go; 1 1 2 1 } 3 1 4 1 if (asset.AssetList != null) { 5 1 6 1 foreach (Asset assetChild in asset.

21、AssetList) { 7 1 8 1 if (assetChild.isLoadFinished) { 9 2 0 2 continue; 1 2 2 2 } else { 3 2 4 2 Asset assetRet = LoadAsset(assetChild); 5 2 6 2 if (assetRet != null) { 7 2 8 2 assetRet.gameObject.transform.parent = asset.gameObject.t

22、ransform; 9 3 0 3 } else { 1 3 2 3 return null; 3 3 4 3 } 5 3 6 3 } 7 3 8 3 } 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0 asset.isLoadFinished true; return asset; 终于开始处理真正的资源了,从缓存中找到WWW对象,调用In sta ntiate方法实例化

23、成 Unity3D 的 gameobject。UpdateGameObject 方法设置 gameobject 各个属性,如位 置和旋转角度。然后又是一个循环递归为了加载子对象,处理gameobject的父子关系。 注意如果LoadAsset返回null,说明www没有下载完毕,等到下一帧处理。最后设置加 载完成标志返回asset对象。 UpdateGameObject 方法: C#代码 01 02 03 04 05 06 07 08 09 private void UpdateGameObject(GameObject go, Asset asset) { //na

24、me go ・ name = asset ・ Name; //position Vector3 vector3 = new Vector3 (( ) asset , (float)asset ・Position[1], (float)asset ・Position[2]); 11 12 13 14 15 16 17 18 19 go.transform.position = vector3; //rotation vector3 = new Vector3 (( ) asset , (float)asset.Rotation[1], (float)asse

25、t.Rotation[2]); go.transform.eulerAngles = vector3; 这里只设置了 gameobject的3个属性,眼力好的同学一定会发现这些对象都是"死 的”,因为少了脚本属性,它们不会和玩家交互。设置脚本属性要复杂的多,编译好的脚 本随着主程序下载到本地,它们也应该通过配置文件加载,再通过C#的反射创建脚本对 象,赋给相应的gameobject。 最后是Scene和asset代码: C#代码 001 002 003 004 005 006 007 008 009 010 011 012 013 014

26、 015 016 017 018 019 020 021 022 023 024 025 public class Scene { public List AssetList { get; set; public class Asset { public const byte TYPE JSON = 1; public const byte TYPE GAMEOBJECT = 2; public Asset() { //default type is gameobject for json load Type = TYPE GAMEOBJ

27、ECT; 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 08

28、0 081 082 083 084 public byte Type { get; set; public string Name { get; set; public string Source { get; set; public double[] Bounds { get; set; public double[] Position { get; set; public double[] Rotation { get; set; public List

29、sLoadFinished { 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 get; set; public WWW www { get; set; public Gam

30、eObject qameObject { get; set; 代码就讲完了,在我实际测试中,会看到gameobject—个个加载并显示在屏幕中, 并不会影响到游戏操作。代码还需要进一步完善适合更多的资源类型,如动画资源,文本, 字体,图片和声音资源。 动态加载资源除了网络游戏必需,对于大公司的游戏开发也是必须的。它可以让游戏 策划(负责场景设计),美工和程序3个角色独立出来,极大提高开发效率。试想如果策 划改变了什么NPC的位置,美工改变了某个动画,或者改变了某个程序,大家都要重新 倒入一遍资源是多么低效和麻烦的一件事。

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

相关资源

更多
正为您匹配相似的精品文档
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!