前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2D MMO中角色动画的优化总结

2D MMO中角色动画的优化总结

作者头像
张晓衡
发布于 2019-09-11 08:32:38
发布于 2019-09-11 08:32:38
1.3K00
代码可运行
举报
运行总次数:0
代码可运行

在深圳Cocos沙龙上,有幸结识了社区中大名顶顶的Colin,Shawn在社区论坛上第一次看到Colin的团队用CocosCreator制作的《热血暗黑》时就被深深地震撼到了!更为重要的是,Colin将他的技术心得和宝贵开发经验写成文字,每一篇分享都是满满的干货。而且幸运的是Shawn得到Colin的授权许可,将他的文章散播到奎特尔星球,我们一起欣赏一起成长!

2D MMO中角色动画的优化总结

1

概述

我们的项目是传统的2D MMO,即人物动画是以图片帧的方式表现的,一个角色大约有8个动作,1个动作有8个方向,1个方向约有10到20帧的图片。这样算起来一个角色由近千张图片帧组成。这样的量对内存和性能都有很高的要求。从立项到目前经历了很多次优化,终于在流畅度和内存占用上达到比较理想的状态。

不知道群里有多少人也在用Creator做类似的MMO手游,我在这里把优化的经历大概写出来供大家参考,也许你们有更好的优化方案,都欢迎一起讨论。

2

最初的实现方案

最初为了快速实现效果,采有很直接的方式:

  • 一个动作一张图集(Plist),8个动作则有8个图集。
  • 每个动作只包含5个方向的图片帧,另外3个方向通过翻转实现。
  • 动画则用Creator提供的动画剪辑(AnimationClip)来实现。

由于一个AnimationClip只能播放一个方向的动画,那么一个角色就需要8*8=64个AnimationClip,如果每个动画剪辑都要在编辑器中编辑,估计美工人员会先晕倒了。

幸好.anim文件是json格式,很容易理解它的含义,于是我们用Python写了一个导出脚本,美术只需要提供角色的所有散图,脚本调用TexturePacker先合成图集,再动态生成anim文件,最后生成一个prefab。

这个prefab就代表一个角色外形。程序的使用就很简单,首次使用先加载Prefab并实例化出结点。从结点取出Animation组件并调用播放接口即可。当角色释放时,把结点收回存到NodePool去,以备下次使用。

3

显示易见的性能问题

从上面的实现看,其实不用Profile也很容易知道会有性能问题,虽然里面使用了NodePool缓存创建过的角色外形。但首次加载这些资源会很卡:一个角色的图集和动画剪辑加起来接近100个文件,想想那个IO压力都觉得蛋疼。

在PC的Web端,这个性能问题没有暴露出来;在安卓甚至苹果机上,一旦旁边有角色进场景,马上就能感受到卡顿,有时甚至能卡上1到2秒。因为我们做的MMO,场景中的玩家进进出出是很平常的,这样的卡顿是不能接受的。

4

优化之一:去掉动画剪裁

首先能想的是去掉anim文件,角色动画其实很简单,只是一些序列帧的播放,并没有用到移动缩放这些动画类型。用anim文件来描述动画有点浪费了,完全可以用另一个简单的Json文件记录动作的信息,比如这个角色有几个动作,每个动作有几个方向,每个方向有几个帧,只要这些信息就够了,类似这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
	"run": [5, 20, 0.033],
	"idle": [5, 4, 0.1],
}

而图集中图片帧的名字,需要有一点规则,即可以通过动作名方向值帧索引这些合成。然后就可以找到对应的图片帧了。

在程序中,仍然是使用AnimationClip来实现动画,只不过它是动态创建的,使用引擎提供的一个APIcc.AnimationClip.createWithSpriteFrames,具体可以参考文档。AnimationClip不用一次性创建出来,可以在播放某个动画时再创建,这样创建的消耗就平摊出来了。我们实现了一个AnimControler组件,通过它来播放动画,而延迟创建动画剪辑这些就顺理成章就封装到组件里面了,外部逻辑不用关心。

这一轮优化下来,一个角色只有动作图集和一个Json文件,去掉了大量的anim文件。包体也因此少了30M大小,算是一个额外好处。

5

优化之二:去掉Plist文件

本以为经过上面的优化,手机上的卡顿应该解决了,但是很不幸,从表现上看只解决了1/3,仍然有0.5到1秒多的卡顿。接下来就各种脑洞和调试了,甚至怀疑加载图片是不是用同步的方式,后来问了@panda,以及自己查看引擎代码,终于确认用的是异步方式。这样的话不应该呀,难道解析Plist文件用了这么长的时间?

后来在调试原生版本时,发现Plist文件原来会按图片帧打散,一个帧就一个json文件,里面描述了帧的位置偏移等信息。想想我们一个角色有近千个帧图片,当加载Plist时,引擎要把所有的Json文件加载进来。这比加载anim文件可蛋疼多了。

既然发现了瓶颈所在,解决方案就自然而然了:去掉Plist文件,只留图片。那么怎么知道每一帧的信息呢,答案还是从Plist中找。我又用万能的Python写了一个工具,把Plist的帧信息提取到上面提到的json文件中去,然后把Plist文件删除。

在程序中,我不再加载cc.SpriteAtlas,而是直接加载cc.Texture2D,然后当创建cc.AnimationClip时,我需要从配置中找到cc.SpriteFrame的纹理信息,然后用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new cc.SpriteFrame.create([Texture2D ] [rect ] [rotated ] [offset ] [originalSize ] )

动态创建帧,把这个帧传入动画剪裁。后面的播放就和原来的一样了。

经过这一次的优化,基本上把IO的负担都消除了,我们在IOS上测试了一下,果然如丝般顺滑,进打怪地图会刷出大量的怪物,也感觉不到卡顿。在安卓上也基本可以接受,在大量角色进来时会有很微小的卡,时间不会超过100毫秒,而因为有了缓存,后面也是顺滑的。至于安卓的这个微卡,我归结为两个:

  • 图片加载进来后解析成纹理的过程。png文件涉及到解压,反编码成raw形式。
  • json文件的加载和解析。json的加载其实是同步的,而解析成JS对象也是需要时间的。

上面这两个其实也和安卓的性能相关。

6

优化之三:压缩角色图片

我们的角色图片用的是png,如果把散图合成一张大图,大概接近于2048*2048,即一个角色加载到内存,会消耗10M以上的内存。再加上角色是可以换装的,一个场景同时出现10个以上的外形是很平常的。光角色这一块就会消耗掉100多M的内存。还是挺让人着急的。

考虑到我们的游戏类型是偏写实的,画面的彩色相对会复杂一些,就决定用PVR,ETC这些格式来看看效果。后面在构建过程中,加入了纹理压缩的流程,IOS用PVR4,安卓用ETC+Alpha,最后的效果完全可以接受,在手机的小屏幕上看不出太大的区别。

PVR4使内存减少了8倍,ETC+Alpha则减少了4倍,这个优化量太可观了,而且附加的好处也很多:

  • 加上压缩的同时用GZip对图片再进行压缩,图片大小比原来的PNG减了3倍,使得程序包又减少了几十M。
  • 由于压缩纹理直接传给GPU,加载纹理只有一个反解压GZip的过程,加载过程也必然大大加快。

7

最后的期望

都说内存,速度,和发热是手游优化的三座大山。但引擎是不大可能完全帮你解决这些问题的,最重要的还是要根据引擎的特点,自己研究出合适项目的优化方案。引擎只需要在底层提供好机制,具体策略由项目去考虑。

对于Creator后面的进化,很希望这几个方向得到加强:

  • JS引擎的效率,Web端的V8已经足够优秀,但原生的SpiderMonkey显然差了很多,官方似乎也在提升原生引擎的版本,期望后续的消息。
  • 类似Unity的AssetBundle,有了这个机制,就可以对资源进行分包,这对大游戏的分包发布很有好处。
  • 工程脚本的分割,游戏里面有大量的策划配置文件,有些动辄上万行,整个工程的脚本合并起来会达到好几M,这对热更新非常不友好的。如果能把脚本分割,每个脚本可以打一个Tag,相同Tag的脚本会合并,这样项目就可以根据自己的情况对脚本进行分离处理了。

最后给大家欣赏一下Colin与他的团队正在开发的游戏《热血暗黑》中的游戏图截:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Creator星球游戏开发社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Cocos2d-x】Cocos2d-x精灵的性能优化
使用纹理图集的优点: 1、减少文件读取次数,读取一张图片比读取一推小文件要快 2、减少OpenGL ES绘制调用并且加速渲染 OpenGL ES 1.1仅仅能够使用2的n次幂大小的图片(即宽度或者高度是2、4、8、64…)。 如果采用小图片OpenGL ES1.1会分配给每个图片2的n次幂大小的内存空间,即使这张图片达不到这样的宽度和高度也会分配大于此图片的2的n次幂大小的空间。那么运用这种图片集的方式将会减少内存碎片。 虽然在Cocos2d-x v2.0后使用OpenGL ES2.0,它不会再分配2的几次幂的内存块了,但是减少读取次数和绘制的优势依然存在。 3、减少内存消耗。 4、Cocos2d-x全面支持Zwoptex和TexturePacker,所以创建和使用纹理图集是很容易的
谙忆
2021/01/21
6220
【Cocos2d-x】Cocos2d-x精灵的性能优化
Cocos Creator 出新版本啦, 2.1.2 圆形Shader终于可以完美解决了!
自 Cocos Creator 2.1.0 发布以来,经过半年时间更新迭代,版本现已趋于稳定,目前 2.1 的新增用户已经占据主流。因此我们计划减少 2.0 版本的后续维护力度,将分散的精力集中投入到引擎后续的发展中,力争将 Cocos Creator 打造成更加专注、开放、健康的开源平台。
张晓衡
2019/09/25
3.2K0
Cocos Creator 出新版本啦, 2.1.2 圆形Shader终于可以完美解决了!
Unity动画系统需要了解的东西,包括:编辑器、事件、资源管理等
导入类动画是通过Unity提供的动画导入器将3D模型导入到Unity项目中的过程。导入过程包括以下步骤:
一凡sir
2023/08/04
9340
【Unity面试篇】Unity 面试题总结甄选 |Unity性能优化 | ❤️持续更新❤️
Unity中,CPU准备好需要绘制的元素,对底层图形程序接口进行调用的过程,每次引擎准备数据并通知GPU的过程称为一次Draw Call。DrawCall越高对显卡的消耗就越大。 降低DrawCall的方法:
呆呆敲代码的小Y
2023/07/24
2.6K0
【Unity面试篇】Unity 面试题总结甄选 |Unity性能优化 | ❤️持续更新❤️
Cocos Creator之脚本使用资源
在 Cocos Creator 中,使用场景文件名(不包含扩展名)来索引指代场景。并通过以下接口进行加载和切换操作:
李小白是一只喵
2021/04/30
1K0
Cocos Creator之脚本使用资源
想做更深入的加载优化?剖析Cocos引擎底层架构后,乐府大佬交出「90分答案」
引言:无论是对引擎研发团队或是游戏开发团队来说,优化的重要性都不言而喻。本次,来自乐府互娱的「乐府小学生」在实际项目开发中,通过修改引擎源码实现了更加深入的加载优化。
张晓衡
2023/02/23
2.7K0
想做更深入的加载优化?剖析Cocos引擎底层架构后,乐府大佬交出「90分答案」
LayaAir 2.0 正式版发布了,重要特性全面介绍
自9月15日首次发布LayaAir 2.0 引擎测试版以来,历时4个多月,推出了4个2.0 beta版本,其中修复BUG若干,2D引擎与IDE优化与新增功能37项,3D引擎与插件优化与新增功能26项。在引擎组团队的不懈努力下,终于为开发者带来了2.0的稳定正式版。在此,也感谢大量参与测试和反馈BUG的开发者。
Layabox Charley
2019/04/30
4.6K0
LayaAir 2.0 正式版发布了,重要特性全面介绍
小游戏内存优化与性能优化
| 导语 听说你的小游戏内存超标?进来了解一下吧。 本文主要跟大家一起来探讨一下Cocos Creator小游戏开发过程中内存优化、性能优化和包体优化。 一、内存优化 因为 iOS小游戏和微信共用同一个进程,而微信在连续两次收到系统内存警告的时候会关闭小游戏并释放小游戏占用的内存。如果你的小游戏有外网用户反馈“闪退”,或者你自己测试的时候频繁出现“该小程序可能导致微信响应变慢被终止”等提示,那么就应该是时候优化你的小游戏内存了! 1、优化双份纹理(必做!) 在你的项目中添加如下代码,就可以减少大
腾讯NEXT学位
2018/09/12
9.2K1
小游戏内存优化与性能优化
游戏性能优化
异名最近负责了一个微信小游戏的项目,在版本迭代间隙对游戏的性能调优进行了一次尝试。这个游戏是个打击类游戏,下面展示一下游戏的预览效果? 性能指标 引擎和小游戏都有提供一个性能面板,给开发者们暴露了下面
异名
2020/07/03
1.9K0
cocos2d-x for android:士兵听我的命令移动
上一篇文章讲述了利用cocos2d-x构建精灵的动画效果,今天打算以此为引子,创建一个在移动时同时指挥角色到我手指触摸的移动地点,那么就开始吧。
全栈程序员站长
2022/07/05
5400
cocos2d-x for android:士兵听我的命令移动
Unity基础动画相关
Animator与Animation区别 1.动画剪辑源文件不同 2.Animator通过AnimatorController蓝图开发,Animation没有。 3.Animation的内存占用比Animator更少
祝你万事顺利
2019/05/29
1.2K0
【Unity游戏开发】初探Unity动画优化
  在最近的优化工作中,马三发现项目中的动画文件内存占比实在是太大了,峰值竟然有200多mb,很明显需要进行优化。经过一番网上查阅资料并结合自己实际操作以后,得到一些需心得体会,在这里马三记录一下并且分享给大家,希望对大家能有一些帮助。
马三小伙儿
2021/06/10
3.3K0
【Unity游戏开发】初探Unity动画优化
Unity性能调优手册4:资源优化,Texture,Mesh,Material,Animation,ParticleSystem,Audio,ScriptableObject
翻译自https://github.com/CyberAgentGameEntertainment/UnityPerformanceTuningBible/ 游戏制作涉及处理大量不同类型的资产,如纹理、网格、动画和声音。本章提供了有关这些资产的实用知识,包括调优性能时要记住的设置。
立羽
2023/10/08
1.8K0
Unity性能调优手册4:资源优化,Texture,Mesh,Material,Animation,ParticleSystem,Audio,ScriptableObject
【02】Cocos游戏开发引擎从0开发一款游戏-cocos项目目录结构熟悉-调试运行项目-最重要的assets资源文件认识-场景sense了解-优雅草卓伊凡
Cocos Creator 项目有着清晰且规范的目录结构,下面为你详细介绍各个主要目录及其功能。
卓伊凡
2025/02/28
1620
显存优化:纹理压缩功能介绍与使用说明
纹理是指物体表面的纹路样式和细腻程度等外观效果。在计算机图形学中,常用于描述三维模型表面图案的二维图形。
Layabox Charley
2020/10/22
3.8K0
显存优化:纹理压缩功能介绍与使用说明
Unity动画☀️一、通过 StringToHash ,控制Animator
并对他身上的Animator进行配置,方便我们使用代码,控制Animator,从而控制这个人物做出各种动作。
星河造梦坊官方
2024/08/14
3030
Unity动画☀️一、通过 StringToHash ,控制Animator
2d像素游戏基本架构
用户11315985
2024/10/16
3170
2d像素游戏基本架构
H5动画开发快车道
前言 以往做一些H5的运营项目,都是动画设计师使用Animate cc(原来的Flash)先设计好动画原型,然后交给我们UI开发来实现。做过动画开发的童鞋都知道动画开发都是比较耗费时间精力的,而且还要高质量的还原动画设计师设计好的动画,来回沟通成本也非常高。 那有没有一种高效的方法来改善这种流程,提高开发效率的同时还能完成高品质的动画呢? 经过一段时间的摸索,发现AnimateCC(就是原来的Flash)可以导出canvas动画,而且是基于createjs这个开发轻量级游戏的js库的,非常适合用来做移动端的
前朝楚水
2018/04/03
5.3K0
H5动画开发快车道
Threejs入门之二十四:Threejs中的Animation动画
Threejs为我们提供了强大的动画系统接口API,通过这些接口,我们可以很轻松的实现物体的移动、旋转、缩放、颜色变化、透明度变化等各种效果,今天我们就来了解下Threejs中的动画系统。 首先我们先了解几个在Threejs动画系统中比较重要的组件
九仞山
2023/04/30
4.4K0
Threejs入门之二十四:Threejs中的Animation动画
你离高效制作动画只差一篇文章的距离
前言       说起动画H5,作为一个前端,可谓是“又爱又恨”。爱的是加上动画动效后H5会变得生动有趣,吸引力Max;恨的是做动画时都是一边在脑海中yy效果,一边用css、js代码模拟出来,既低效又
腾讯ISUX
2018/06/29
1.3K0
推荐阅读
相关推荐
【Cocos2d-x】Cocos2d-x精灵的性能优化
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验