unity ParticleSystem 实现序列帧动画效果(一)

用粒子系统实现序列帧动画优势:

先附上一个 介绍序列帧实现方式比较的链接 点击打开链接

在该链接里说较为倾向于使用该方式俩实现序列帧动画,那么具体的好处又有哪些呢?

此处再贴一个链接,这里介绍了下粒子系统的更新和性能优化方面的一些小提示:

        (https://unity3d.com/cn/how-to/particle-systems-performance-tips)

        看过以上链接可以知道,粒子系统可以动态合批且添加了Sprite Support,那么这样我们就可以考虑大量的序列帧动画同屏显示的时候,粒子系统来实现它会是一个非常“省事”且“使用”的方法,同时我们也可以用TexturePacker来生成精灵图集,满足节约图集的需求,由此看来粒子系统的确是一个很好的选择。

具体实现方式:

首先如果需要实现序列帧动画我们需要的是粒子系统中的以下组件:

unity ParticleSystem 实现序列帧动画效果(一)_第1张图片

也就是说我们初始化创建的粒子系统,只需要初始设置、TextureSheetAnimation和Renderer

(1)TextureSheetAnimation

实现序列帧动画,TextureSheetAnimation承担了大部分的配置:

unity ParticleSystem 实现序列帧动画效果(一)_第2张图片

上图是在Mode为Grid时,TextureSheetAnimation的相关参数,这里主要是支持——完全相同大小的精灵在同一图集中通过正交裁切出多个精灵进行序列帧播放(如果我们需要用TexturePacker来实现,是需要不同大小甚至是网格形式来实现,那么这里的模式自然是不支持的),因为跟本文介绍无关,所以在此处挂上链接,如有需要此方式实现,可以参照这里Unity3D:粒子特效(Particle System)播放序列帧动画

接下来来介绍另一个Mode,Sprites,通过选择Sprites来切换:

unity ParticleSystem 实现序列帧动画效果(一)_第3张图片

切换完之后,参数会有些许变动:

unity ParticleSystem 实现序列帧动画效果(一)_第4张图片

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可进行自定义

(a)精灵的导入与TexturePacker

    上文说过可以手动添加或者通过代码来添加精灵,但是怎么样与TexturePacker结合使用呢?当我们用TexturePacker生成图集的时候会发现,可以选用矩形,正方形或者网格等等的形式来进行图集打包,其中网格的占用空间最少,其次是矩形然后就是最大的正方形。

    为了能够在粒子系统里嵌入TP打出的图集,通过查阅资料发现,粒子系统并不支持多边形精灵但是支持不同大小的精灵。因此我们的图集打包方式就不能采用多边形网格的形式来打包,便选用了比较折中的矩形的方式。

    同时粒子系统需要知道精灵的轴心和具体位置,来保证动画播放不会出现轴心便宜和抖动,所以在打包图集的时候一定要保证记录下图的位置信息。

(b)FlipUV与正常的镜像区别

    之所以会研究到翻转UV是因为,如果我们选择镜像,可以保证8方向中3个方向的精灵是可以被省略的,只需要左右镜像即可。

    最开始的实现方式是:运用FlipU来实现

    实现之后会发现,虽然镜像实现,但是精灵会出现抖动的现象,这就说明这里不仅改变了UV的翻转,同时也改变了轴心,所以从这里来看,这里不是仅仅对UV的翻转,同时也会将内部精灵信息做调整。 

    最后选用的实现方式是:直接改变Particle的size3D属性,将size3D.x = -1

    这样的实现就很完美的实现了镜像,也可以保证各个粒子进行镜像,而不是整个粒子系统镜像。

(c)Frame over Time 和 Cycles 

接着对Frame over Time 和 Cycles 这两个参数做一个详细解释:

首先来看一下Frame over Time:

unity ParticleSystem 实现序列帧动画效果(一)_第5张图片

这是一个曲线,横轴不可变恒定为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)并不是从头开始的循环,而是依次往前进行的循环,例如第一个循环显示了第一帧,那么接下来的循环会显示第二帧。。。。这里的确是一个很让人迷惑的点,关于参数的名称和实际效用有一定的冲突,所以希望有对这个比较了解的朋友可以评论下具体的原因。

(2)Renderer

想要了解Renderer相关参数,可以访问以下链接来进行学习和了解( https://www.jianshu.com/p/60b41616981c)

unity ParticleSystem 实现序列帧动画效果(一)_第6张图片

我们针对粒子系统实现序列帧所需要了解的参数(RenderMode、Material、SortMode、Render Alignment)

如果已经看过参数介绍的话,那么如果要实现序列帧动画需要按照如下设置:

unity ParticleSystem 实现序列帧动画效果(一)_第7张图片

其中SortMode需要设置成ByDistance这样可以根据在场景中离摄像机远近来进行排序绘制

同时RenderAlignment设置成World,来保证粒子是始终保持一个角度绘制,而不是始终面对相机(选择view会始终面对相机)

Sorting Fudge这个参数是用来控制粒子的渲染顺序的,数值越小,越会绘制在上层

(3)粒子系统与粒子

    我们先来了解下粒子系统中,那些是目前我们需要使用的参数或对象:

    粒子系统(Particle System)

    系统中的参数主要作用就是用来发射粒子,所以基本都是对Renderer的参数设置

    例如Renderer.Material、Renderer.SortingFudge等等

    其中我们需要利用粒子系统做的,就是

    *发射粒子:Emit()

    *管理粒子数组:ParticleSystem.Particle[],关于粒子的管理,粒子系统只提供了两个方法,SetParticles()和GetParticles()


    粒子(Particle)

    粒子本身就是我们实现序列帧动画的主要操作对象,属于值类型。首先我们可以看一下粒子本身所带有的参数:

Properties

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.

    上表中灰色的表示在我们的系统中不需要处理的参数,也是不太需要的参数。红色的相关参数,基本是我们实现序列帧动画的关键,接下来我们会针对这些参数来介绍,并讲解怎么来实现序列帧动画。

    (a)position、rotation3D、startSize3D

        position:这个参数控制了粒子在场景中的位置,通过设置这个值,就能在场景中的各个地方创建粒子,同时也可以实时改变这个参数,来实现粒子的位移

        rotation3D:这个参数用来保证粒子的朝向,因为之前设置的粒子RenderAlignment为World,所以可以通过设置朝向来实现固定朝向的粒子。

        startSize3D:这个参数是用来控制粒子的大小的参数,之前我们介绍过,通过将startSize3D.x设置成-1,这样就可以实现镜像,同时之后会通过这个参数,来做一些关于粒子大小偏移的操作。

    (b)startLifeTime和remainingLifeTime(标红来表示强调!!)

        这两个参数是控制粒子生命周期的两个参数,startLifeTime是开始的生命周期,remainingLifeTime是剩余的生命周期。

        这两个参数原本是来控制粒子生命周期的参数,但是同时,它们也控制着当前的粒子所播放的序列帧。

        例如我们的生命周期(StartLifeTime)设置的值为5,那么指的是这个粒子的全部生命周期为5

        接下来,粒子的remainingLifeTime与StartLifeTime的比值决定了他当前所播放的序列帧。


        我们来举例说明一下,假设是一个180帧的序列帧动画:

        如果StartLifeTime = 5,RemainingLifeTime = 5,那么会播放第1帧

        如果StartLifeTime = 5,RemainingLifeTime = 4,那么会播放第37帧


        所以简单来说,决定粒子播放动画的哪一帧是由RemainingLifeTime和StartLifeTime来决定的,那么这两个参数,就是我们让粒子系统按照自己期望的方式播放动画的关键。

总结

根据如上信息,我们可以发现,我们能够通过控制粒子和粒子系统,帮助我们来实现具体的序列帧动画。下一篇我会具体的根据这些属性,来讲解具体的实现方式和实现方案。

你可能感兴趣的:(unity)