先附上一个 介绍序列帧实现方式比较的链接 点击打开链接
在该链接里说较为倾向于使用该方式俩实现序列帧动画,那么具体的好处又有哪些呢?
此处再贴一个链接,这里介绍了下粒子系统的更新和性能优化方面的一些小提示:
(https://unity3d.com/cn/how-to/particle-systems-performance-tips)
看过以上链接可以知道,粒子系统可以动态合批且添加了Sprite Support,那么这样我们就可以考虑大量的序列帧动画同屏显示的时候,粒子系统来实现它会是一个非常“省事”且“使用”的方法,同时我们也可以用TexturePacker来生成精灵图集,满足节约图集的需求,由此看来粒子系统的确是一个很好的选择。
首先如果需要实现序列帧动画我们需要的是粒子系统中的以下组件:
也就是说我们初始化创建的粒子系统,只需要初始设置、TextureSheetAnimation和Renderer
(1)TextureSheetAnimation
接下来来介绍另一个Mode,Sprites,通过选择Sprites来切换:
切换完之后,参数会有些许变动:
SpritesMode支持导入精灵来实现序列帧动画,因此TexturePacker导出的图集生成的精灵可以直接导入其中来进行设置,可以通过这里的 +号 添加精灵,也可以通过代码手动添加,具体API可查询文档,就不在阐述了
接下来对这里的参数来进行简单的说明(因为实现时跟官方文档描述有一定的出入,这里多数是自己在实验过后的理解)
首先列举下所有参数及介绍:
Frame over Time:每个循环播放,帧随循环内时间的增加而变化的曲线设置(此处的循环与cycles有关,且循环不从0开始计数)
Start Frame:开始的帧是哪一帧
Cycles:(这里是自己测试得到的一个解释)一个生命周期里序列帧动画播放的循环次数,这里应该控制着
Flip U: 根据U进行翻转
Flip V: 根据V进行翻转
Enabled UV Channels: 开启的UV通道(unity支持4套UV,UV0用于主纹理, UV1用于光照贴图, UV2用于实时动态光照, UV3可进行自定义)
上文说过可以手动添加或者通过代码来添加精灵,但是怎么样与TexturePacker结合使用呢?当我们用TexturePacker生成图集的时候会发现,可以选用矩形,正方形或者网格等等的形式来进行图集打包,其中网格的占用空间最少,其次是矩形然后就是最大的正方形。
为了能够在粒子系统里嵌入TP打出的图集,通过查阅资料发现,粒子系统并不支持多边形精灵但是支持不同大小的精灵。因此我们的图集打包方式就不能采用多边形网格的形式来打包,便选用了比较折中的矩形的方式。
同时粒子系统需要知道精灵的轴心和具体位置,来保证动画播放不会出现轴心便宜和抖动,所以在打包图集的时候一定要保证记录下图的位置信息。
之所以会研究到翻转UV是因为,如果我们选择镜像,可以保证8方向中3个方向的精灵是可以被省略的,只需要左右镜像即可。
最开始的实现方式是:运用FlipU来实现
实现之后会发现,虽然镜像实现,但是精灵会出现抖动的现象,这就说明这里不仅改变了UV的翻转,同时也改变了轴心,所以从这里来看,这里不是仅仅对UV的翻转,同时也会将内部精灵信息做调整。
最后选用的实现方式是:直接改变Particle的size3D属性,将size3D.x = -1
这样的实现就很完美的实现了镜像,也可以保证各个粒子进行镜像,而不是整个粒子系统镜像。
接着对Frame over Time 和 Cycles 这两个参数做一个详细解释:
首先来看一下Frame over Time:
这是一个曲线,横轴不可变恒定为1,纵轴可修改,这个值控制的是Frame数。在FrameOverTime参数中有相关的乘数
frameOverTimeMultiplier | Frame over time mutiplier. |
这里的乘数的作用目前看来是:FrameOverTime.y = frameOverTimeMultiplier * Sprites.Count(动画帧数量 )
横轴的 1 大部分文章中介绍都是1s或者一个生命周期,其实在我的测试结果看来这里是 一个循环
也就是说,当Cycles为1的时候,就代表着这个生命周期内帧变化会按照曲线控制来展示。
还有一个点就是,当我们把Cycles设置成Sprites.Count(动画帧数量 ),frameOverTimeMultiplier设置成1/Sprites.Count(动画帧数量 ),这里动画的实现效果与Cycles设置成1,frameOverTimeMultiplier也设置成1的效果完全一致。
这也就说明,这个循环(Cycles)并不是从头开始的循环,而是依次往前进行的循环,例如第一个循环显示了第一帧,那么接下来的循环会显示第二帧。。。。这里的确是一个很让人迷惑的点,关于参数的名称和实际效用有一定的冲突,所以希望有对这个比较了解的朋友可以评论下具体的原因。
想要了解Renderer相关参数,可以访问以下链接来进行学习和了解( https://www.jianshu.com/p/60b41616981c)
我们针对粒子系统实现序列帧所需要了解的参数(RenderMode、Material、SortMode、Render Alignment)
如果已经看过参数介绍的话,那么如果要实现序列帧动画需要按照如下设置:
其中SortMode需要设置成ByDistance这样可以根据在场景中离摄像机远近来进行排序绘制
同时RenderAlignment设置成World,来保证粒子是始终保持一个角度绘制,而不是始终面对相机(选择view会始终面对相机)
Sorting Fudge这个参数是用来控制粒子的渲染顺序的,数值越小,越会绘制在上层
我们先来了解下粒子系统中,那些是目前我们需要使用的参数或对象:
粒子系统(Particle System)
系统中的参数主要作用就是用来发射粒子,所以基本都是对Renderer的参数设置
例如Renderer.Material、Renderer.SortingFudge等等
其中我们需要利用粒子系统做的,就是
*发射粒子:Emit()
*管理粒子数组:ParticleSystem.Particle[],关于粒子的管理,粒子系统只提供了两个方法,SetParticles()和GetParticles()
粒子(Particle)
粒子本身就是我们实现序列帧动画的主要操作对象,属于值类型。首先我们可以看一下粒子本身所带有的参数:
angularVelocity | The angular velocity of the particle. |
angularVelocity3D | The 3D angular velocity of the particle. |
animatedVelocity | The animated velocity of the particle. |
position | The position of the particle. |
randomSeed | The random seed of the particle. |
remainingLifetime | The remaining lifetime of the particle. |
rotation | The rotation of the particle. |
rotation3D | The 3D rotation of the particle. |
startColor | The initial color of the particle. The current color of the particle is calculated procedurally based on this value and the active color modules. |
startLifetime | The starting lifetime of the particle. |
startSize | The initial size of the particle. The current size of the particle is calculated procedurally based on this value and the active size modules. |
startSize3D | The initial 3D size of the particle. The current size of the particle is calculated procedurally based on this value and the active size modules. |
totalVelocity | The total velocity of the particle. |
velocity | The velocity of the particle. |
上表中灰色的表示在我们的系统中不需要处理的参数,也是不太需要的参数。红色的相关参数,基本是我们实现序列帧动画的关键,接下来我们会针对这些参数来介绍,并讲解怎么来实现序列帧动画。
position:这个参数控制了粒子在场景中的位置,通过设置这个值,就能在场景中的各个地方创建粒子,同时也可以实时改变这个参数,来实现粒子的位移
rotation3D:这个参数用来保证粒子的朝向,因为之前设置的粒子RenderAlignment为World,所以可以通过设置朝向来实现固定朝向的粒子。
startSize3D:这个参数是用来控制粒子的大小的参数,之前我们介绍过,通过将startSize3D.x设置成-1,这样就可以实现镜像,同时之后会通过这个参数,来做一些关于粒子大小偏移的操作。
这两个参数是控制粒子生命周期的两个参数,startLifeTime是开始的生命周期,remainingLifeTime是剩余的生命周期。
这两个参数原本是来控制粒子生命周期的参数,但是同时,它们也控制着当前的粒子所播放的序列帧。
例如我们的生命周期(StartLifeTime)设置的值为5,那么指的是这个粒子的全部生命周期为5
接下来,粒子的remainingLifeTime与StartLifeTime的比值决定了他当前所播放的序列帧。
我们来举例说明一下,假设是一个180帧的序列帧动画:
如果StartLifeTime = 5,RemainingLifeTime = 5,那么会播放第1帧
如果StartLifeTime = 5,RemainingLifeTime = 4,那么会播放第37帧
所以简单来说,决定粒子播放动画的哪一帧是由RemainingLifeTime和StartLifeTime来决定的,那么这两个参数,就是我们让粒子系统按照自己期望的方式播放动画的关键。
根据如上信息,我们可以发现,我们能够通过控制粒子和粒子系统,帮助我们来实现具体的序列帧动画。下一篇我会具体的根据这些属性,来讲解具体的实现方式和实现方案。