用Unity重现《空洞骑士》的苦痛之路(4)——特效篇

作者:繁华如梦 2019-04-15
作者繁华如梦授权游资网转载

前言:

终于来到本系列的最后一篇,感觉整个人都快肝废了。本来想鸽的,最终凭着最后一点肝续了下来。


在之前的篇章中,我们已经完成游戏主体的搭建。接下来只需要添加上对应的特效,就能够使整个游戏变得更加完整。(PS:本期中代码并没有过多讲解且并不完整,说得最多的是思路,还请留意)

超级冲刺特效

超级冲刺的特效大致是由4种特效组合来完成的,分别是:

1.冲刺特效

2.聚集特效

3.聚集完成特效

4.地面水晶

在上面的的特效中,某一部分由于找不到对应的图片,将不会与原版一样,而且其中还有与人物动画进行配合的部分,将不会实现类似的细节。还请各位童鞋留意。

聚集与冲刺特效

聚集状态与冲刺状态下的特效,都是使用的帧动画来进行制作的。在合适的地方播放该帧动画即可。此处就不在多说了。

聚集完成特效

聚集完成的特效,由于缺少相关的序列帧,此处只能自己搭建图像来近似相关的图像以及动画。流程就是,先参照原版游戏特效画面,自己通过游戏素材搭建出一帧帧画面,并通过代码控制物体的显示,来模拟出相应的效果。(还好这个只有4帧,多了我还真的吃不消)大致帧序列如下:

聚集完成特效序列帧

(盗文章的人实在是太多了,不知道加水印是否有用)

地面水晶

在超级冲刺的时候,地面会随时间向上生成紫色的水晶,并向周围扩散生成。其中有一个小细节,就是水晶只会生成在地面,在空中不会进行生成。此处,我们偷一下懒,水晶并不是动态生成,而是一开始搭建好的,然后在需要生成的时候,通过朝地面打射线的方式判断是否在地面,来决定是否显示水晶。如下图:

一开始搭建好的水晶特效物体

特效组合后效果如下:

完整的超级冲刺特效

代码大致如下。其中考虑到在墙上的超级冲刺,需要事先设定好转向的旋转信息,防止动态修改出现误差:

  1.   Quaternion leftQua;                 //超级冲刺特效地面水晶在墙上的旋转
  2.     Quaternion rightQua;
  3.     GameObject particleObj;     //超级冲刺物体(紫色水晶)
  4.     void Start()
  5.     {
  6.         particleObj.transform.Rotate(new Vector3(0, 0, -90));//初始化左右旋转后的四元素,用于后面特效转向
  7.         leftQua = particleObj.transform.rotation;
  8.         particleObj.transform.Rotate(new Vector3(0, 0, 180));
  9.         rightQua = particleObj.transform.rotation;
  10.         particleObj.transform.Rotate(new Vector3(0, 0, -90));
  11.     }
  12.     public void SuperSprintFunc()
  13.     {
  14.         if (Input.GetKeyDown(InputManager.Instance.superKey))
  15.         {
  16.             ....
  17.         }
  18.         else if (Input.GetKey(InputManager.Instance.superKey))
  19.         {
  20.             ....
  21.             LookParticObj();
  22.         }
  23.     }
  24.     public void LookParticObj()
  25.     {
  26.         GameObject tempObj = particleObjs[lookLevel];//particleObjs 数组存储所有的特效(水晶)物体
  27.         SpriteRenderer[] renderers = tempObj.GetComponentsInChildren<SpriteRenderer>(true);
  28.         for (int i=0;i<renderers.Length;i++)
  29.         {
  30.             ParticObjIsLook(renderers[i].transform);
  31.         }
  32.     }
  33.     public bool ParticObjIsLook(Transform objTrs)
  34.     {
  35.         RaycastHit2D hit2D;
  36.         if (isClimb)        //如果进行了爬墙状态 射线发射方向改变
  37.         {
  38.             if (nowDir == PlayDir.Right)
  39.             {
  40.                 hit2D = Physics2D.Raycast(objTrs.position, Vector3.right, boxSize.y, playerLayerMask);
  41.             }
  42.             else
  43.             {
  44.                 hit2D = Physics2D.Raycast(objTrs.position, Vector3.left, boxSize.y, playerLayerMask);
  45.             }
  46.         }
  47.         else
  48.         {
  49.             hit2D = Physics2D.Raycast(objTrs.position, Vector3.down, boxSize.y, playerLayerMask);
  50.         }
  51.         if (hit2D.transform!=null)
  52.         {
  53.             objTrs.gameObject.SetActive(true);
  54.             return true;
  55.         }
  56.         objTrs.gameObject.SetActive(false);
  57.         return false;
  58.     }
复制代码

二段跳特效

二段跳特效也是使用2种特效来组合完成的。分别是二段跳的翅膀光翼,以及落下的羽毛特效。光翼没有对应的素材,此处直接跳过。只使用Unity的粒子系统来制作与羽毛落下的效果。

制作特效前,首先先找到对应的羽毛图片,如下:(注:此处图片是我在PS中切出来的3张单独的图片。)

3张不同形态的羽毛图

然后为3张不同的羽毛新建不同的材质。之后在着色器选项中,选择Particles/Additive,再在后续的选项选择素材羽毛图片即可。虽然2D的精灵图应该是使用着色器Sprites/Default,但是我们这里选择粒子特效的着色器,效果更好(PS:着色器可以自由选择,你觉得好看就行)。如下图:

新建材质属性

接下来新建一个空物体,并添加上粒子系统组件(Particle System),在Renderer(渲染)模块下的material选项,选择我们创建好的材质。如下图:

粒子系统材质赋予

在这里简单说一下我们会用到的属性。

Duration(粒子发射的持续时间)

Start Lifetime(粒子的存活时间)

Start Speed(粒子的速度)

Gravity Modifier(重力修正,可以理解为重力的倍数)

粒子系统主模块图

Emission(发射模块)

Rate over Time(单位的时间发出的粒子数)

Rate over Distance(单位的移动距离发出的粒子数)

粒子系统发射模块图

Shape(形状模块)

Shape(粒子发射的形状)

Radius(半径)

粒子系统形状模块图

Size over Lifetime(粒子大小随时间变化模块)

Separate Axes(勾选该选项,分开处理3轴属性)

Size(调整对应属性,粒子的大小在生命周期内会按照曲线进行变化)

粒子系统粒子大小模块

Rotation Over Lifetime(粒子旋转随时间变化模块)

Separate Axes(勾选该选项,分开处理3轴属性)

Angular velocity(角速度)(PS:由于是2d物体,此处只需要绕Z轴的旋转速度)

粒子系统粒子旋转模块

值得注意的是,上面的选项除了Duration,其余都是支持自定义曲线模式,来编辑粒子系统播放时数值随时间的变化。如下图:

粒子系统曲线编辑模式

接下来就是根据羽毛特效,来调整对应的参数了。(PS:上面的模块截图属性就是我使用的)由于上面的大部分属性都是使用了曲线模式来进行编辑的,这些参数根据自己的理解来进行设置即可。同时,为了羽毛特效的形态不同,我们还需要在为其余的2张不同形态的羽毛制作2个粒子特效,并将这3个特效制作为一个预制体,来完成这一效果!完成后如下图:

羽毛粒子效果

暗影冲刺特效

拖尾粒子

在进行暗影冲刺的时候,玩家身后会出现一条由黑色小圆点组成的拖尾。本质是一个拖尾粒子。制作同上,素材只需要一张黑色的小圆点图片,只不过不需要随时间进行粒子的生成,而是随移动距离来生成粒子。即Rate over Time数值为0,Rate over Distance数值按需调整即可。由于是圆形粒子,跟随时间的旋转也可以取消。完成后如下图:

暗影冲刺粒子效果

然后就是在代码中,暗影冲刺开始时生成对应的特效物体,让特效物体随玩家进行移动,在暗影冲刺结束时停止跟随,并在一段时间后销毁特效物体。代码比较简单,这里就不在贴出了。

拖尾与回复动画

在播放暗影冲刺动画时,还附带有拖尾的帧动画,以及暗影冲刺能量回复的帧动画。一开始制作好相应的帧动画物体,并放在玩家的节点下,在冲刺开始以及结束的时候播放对应动画即可。动画如下:

回复与拖尾帧动画

暗影冲刺动画

在原作中,暗影冲刺在地上进行冲刺,与在空中进行冲刺略有不用。需要在播放动画时,进行判断,此处需要注意!动作如下:

不同的冲刺序列帧

特效物体组合后效果如下:

暗影冲刺特效演示

攻击交互特效

玩家攻击到不同的物体将会有不同的特效提示,此处摸一下鱼,只制作攻击碰撞到陷阱的交互特效。

仍然先将特效的帧动画制作出来。如下:

攻击交互帧动画

然后在代码中,攻击检测时进行生成对应的帧动画物体。需要注意的是,不同的攻击方向,生成的物体方向也是不一样的,代码大致如下:

  1.   public void CheckAckInteractive(int dir) //参数为当前的攻击方向
  2.     {
  3.         float distance = 1.8f;          //射线的检测长度
  4.         RaycastHit2D hit2D = new RaycastHit2D();
  5.         Vector2 raySize = new Vector2(boxSize.x , boxSize.y);         //射线的大小
  6.         switch (dir)
  7.         {
  8.             case 1:
  9.                 hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.left, distance, playerLayerMask);
  10.                 break;
  11.             case 2:
  12.                 hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.right, distance, playerLayerMask);
  13.                 break;
  14.             case 3:
  15.                 hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.up, distance, playerLayerMask);
  16.                 break;
  17.             case 4:
  18.                 hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.down, distance, playerLayerMask);
  19.                 break;
  20.         }
  21.         if (hit2D.collider != null)
  22.         {
  23.             if (hit2D.collider.gameObject.CompareTag("Trap"))   //如果是陷阱就有后坐力
  24.             {
  25.                 var tempObj = Instantiate(attactEffectObj, hit2D.point, Quaternion.identity);//攻击交互特效
  26.                 switch (dir)//根据攻击方向旋转特效物体
  27.                 {
  28.                     case 1:
  29.                         tempObj.transform.rotation = Quaternion.Euler(new Vector3(0, 0, -90));
  30.                         break;
  31.                     case 2:
  32.                         tempObj.transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90));
  33.                         break;
  34.                     case 3:
  35.                         tempObj.transform.rotation = Quaternion.Euler(new Vector3(0, 0, 180));
  36.                         break;
  37.                     case 4://默认方向不需要修改
  38.                         break;
  39.                 }
  40.             }
  41.     }
复制代码

结语

本系列到了现在项目算是完结了。虽然我漏掉了音效添加以及一些其余的细节内容,但是完整工程上面其实已经添加上去了对应的内容,需要的童鞋可以下载了解。文章后面还会有一个打包后游戏文件,欢迎下载试玩。(PS:封面沙雕图来源于百度贴吧 磁力菇1210)

工程下载链接

工程链接:https://pan.baidu.com/s/1l3zbN8GScoAR3wp3eHp5sQ提取码:qd8h
相关链接,很(mai)重(mai)要(mai)
空洞骑士购买链接:https://store.steampowered.com/app/367520/Hollow_Knight/
有线下学习游戏开发打算的童鞋,欢迎访问http://levelpp.com/
线上课程的传送门如下:简明易懂的C#入门指南-网易云课堂study.163.com
另有专业开发交(gao)流(ji)群等待大家强势插入:869551769

系列文章:
用Unity重现《空洞骑士》的苦痛之路(1):动作篇
用Unity重现《空洞骑士》的苦痛之路(2)——人物控制篇
用Unity重现《空洞骑士》的苦痛之路(3)——地图篇
用Unity重现《空洞骑士》的苦痛之路(4)——特效篇

作者:繁华如梦
专栏地址:https://zhuanlan.zhihu.com/p/61876044

最新评论
暂无评论
参与评论

商务合作 查看更多

编辑推荐 查看更多