Unity项目中的资源更新

射击游戏项目开发笔记 (四)

项目可用目录说明:(android为例)

一般的android程序可读的目录有

  • 包本身的外部资源目录,资源不参与签名(APK的Assets文件夹下,实际位置 data/app/包ID.apk) 仅可读
  • 包本身的内部自由目录,资源参与签名(APK的res文件夹下) 仅可读
  • 系统分配的用户目录(实际位置一般是 data/data/包ID/files) 可读写
  • 手机存储 / SD卡内 可读写

资源加载规则

0.从包内文件中加载
1.资源加载模块直接提供从包内文件和从用户目录(或者SD卡某目录)两种加载路径
2.游戏第一次启动时,将包内文件全部copy到用户目录,或者SD卡目录,下载文件也下载到这个目录,然后统一在这个目录加载(这是我之前的项目的方式,现在看来是有问题的)

咱们项目我认为第1种方式是比较可取的.原因如下:

如果我们只使用第0种,则每次更新资源,哪怕一张图片而已 都需要更新应用程序,相当不划算.但是资源加载方式不能抛弃,毕竟手机流量寸土寸金,除非应用程序完全不包含游戏资源.不包含游戏资源的应用程序从体积上当然是最小的,但是玩家第一次启动游戏就需要立马下载资源.从 下载游戏 – 安装游戏 – 启动游戏 – 下载资源 – 加载资源 – 游玩 .这个过程太过缓慢,每为玩家增加一个步骤 流失的几率就大很多.

如果我们使用第2种,则是把整个游戏的资源均放在应用程序的可读写用户目录里(这个目录可以是SD卡也可以是应用程序本身的用户目录).从资源复用的方面讲,就白白浪费了应用程序包文件里的资源.(倘若我们游戏 应用程序 与 资源 完全分开 则这种方式可取.)

反观第1种,相比 0,2来说,代价是需要维护一个资源文件加载路径配置文件,例如加载图片A.jpg,在真正载入之前需要判断应该从包文件内 还是 可读写的资源目录中加载.这样做到了空间利用最大化.

资源分包更新 – 若我们资源过大,满足玩家玩到不同阶段然后再下载分开的资源包

分包操作需要策划执行.大概的思路应该是根据不同等级 而把不同的资源分包.根据玩家等级来判断是否需要下载资源.

好处:玩家首次下载的资源能减小,相对来说比较容易推

坏处:每次玩家升级都需要判断,而且在运营游戏的过程中,如果有资源需要改变 则伴随着分包的改变.每个分包修改都会非常频繁.

资源补丁更新 – 资源包的形式(管理补丁包的版本号),单文件的形式(管理全部子资源的版本号)

  • 资源打包的形式(管理补丁包的版本号)

每次更新补丁,都需要把需要更新的文件打包到一个zip(或rar 7z什么的)文件里.然后给补丁包一个版本号.在用户启动游戏的时候下载更新.

带来的好处: 是能清晰的查看每次资源更新更新了什么.而且游戏资源出错概率相对 单文件的形式 来说比较低.(我这个结论怎么下的?这个结论是不怎么能站得住脚的 因为这是我的自我感觉..),下载可以只下载一个文件.

带来的问题: 玩家需要更新每一个补丁包才能进入游戏.倘若有3个补丁包,文件组织如下:

version001 有 A.jpg B.ogg C.mp3 D.png
version002 有 B.ogg C.mp3 E.png
version003 有 C.mp3 F.png

玩家需要依次更新version 001 002 003 总共 9个文件,浪费了 一个 B.ogg,两个C.mp3 的流量.

  • 单文件的形式(管理全部子资源的版本号)

为每个资源文件构建一个版本号(推荐用MD5或者其他算法得出一个文件唯一的字符串来做版本号),形成一个版本号文件,在每次玩家启动的时候 对比 本地 和服务器 上的版本.把需要更新的 下载更新.

带来的好处: 运营不在需要维护补丁包,仅仅需要维护一个服务器的版本文件即可.用户不再需要下载 某个资源的每个版本(例如上面的C.mp3的三个版本),而是每次下载都是最新的版本.节省了流量.

带来的问题: 维护整个项目的每个资源的版本号,相对于维护每次更新的版本号来说 量大了,毫无疑问出错概率肯定高了.下载更新 需要下载N个文件.在下载文件过程中出错概率会增高.

应用程序的更新 – Android & iOS

  • 若有新的app 则下载到指定目录(for android and iOS越狱版)
  • 若有新的app 则弹到app store界面(iOS 应用商店版)
  • android 在 Unity中使用AndroidJavaObject获取事先实现的自我安装代码.
  • iOS越狱版 使用itms-services协议

程序脚本更新的可能 – .so更新 .dll更新

.so更新 暂时不了解Unity的.so加载机制.(待项目中期讨论)
.dll更新 学习了一下反射调用,但是感觉并不能满足需求.(待项目中期讨论)

参考

http://www.cnblogs.com/crazylights/p/3884650.html
http://blog.csdn.net/janeky/article/details/25923151
http://shadowkong.com/archives/1438

2 评论

  1. 如果有cocos2d-js的经验,接触过jsbinding,可以搜索一下unity3d下的jsbinding方案,把c#转换成纯正的javascript,能够热更新逻辑。

发表评论

电子邮件地址不会被公开。 必填项已用*标注