用Unity重現《空洞騎士》的苦痛之路(4)——特效篇
前言:
終於來到本系列的最後一篇,感覺整個人都快肝廢了。本來想鴿的,最終憑著最後一點肝續了下來。
在之前的篇章中,我們已經完成遊戲主體的搭建。接下來只需要新增上對應的特效,就能夠使整個遊戲變得更加完整。(PS:本期中程式碼並沒有過多講解且並不完整,說得最多的是思路,還請留意)
超級衝刺特效
超級衝刺的特效大致是由4種特效組合來完成的,分別是:
1.衝刺特效
2.聚集特效
3.聚集完成特效
4.地面水晶
在上面的的特效中,某一部分由於找不到對應的圖片,將不會與原版一樣,而且其中還有與人物動畫進行配合的部分,將不會實現類似的細節。還請各位童鞋留意。
聚集與衝刺特效
聚集狀態與衝刺狀態下的特效,都是使用的幀動畫來進行製作的。在合適的地方播放該幀動畫即可。此處就不在多說了。
聚集完成特效
聚集完成的特效,由於缺少相關的序列幀,此處只能自己搭建影像來近似相關的影像以及動畫。流程就是,先參照原版遊戲特效畫面,自己通過遊戲素材搭建出一幀幀畫面,並通過程式碼控制物體的顯示,來模擬出相應的效果。(還好這個只有4幀,多了我還真的吃不消)大致幀序列如下:
聚集完成特效序列幀
(盜文章的人實在是太多了,不知道加水印是否有用)
地面水晶
在超級衝刺的時候,地面會隨時間向上生成紫色的水晶,並向周圍擴散生成。其中有一個小細節,就是水晶只會生成在地面,在空中不會進行生成。此處,我們偷一下懶,水晶並不是動態生成,而是一開始搭建好的,然後在需要生成的時候,通過朝地面打射線的方式判斷是否在地面,來決定是否顯示水晶。如下圖:
一開始搭建好的水晶特效物體
特效組合後效果如下:
完整的超級衝刺特效
程式碼大致如下。其中考慮到在牆上的超級衝刺,需要事先設定好轉向的旋轉資訊,防止動態修改出現誤差:
- Quaternion leftQua; //超級衝刺特效地面水晶在牆上的旋轉
- Quaternion rightQua;
- GameObject particleObj; //超級衝刺物體(紫色水晶)
- void Start()
- {
- particleObj.transform.Rotate(new Vector3(0, 0, -90));//初始化左右旋轉後的四元素,用於後面特效轉向
- leftQua = particleObj.transform.rotation;
- particleObj.transform.Rotate(new Vector3(0, 0, 180));
- rightQua = particleObj.transform.rotation;
- particleObj.transform.Rotate(new Vector3(0, 0, -90));
- }
- public void SuperSprintFunc()
- {
- if (Input.GetKeyDown(InputManager.Instance.superKey))
- {
- ....
- }
- else if (Input.GetKey(InputManager.Instance.superKey))
- {
- ....
- LookParticObj();
- }
- }
- public void LookParticObj()
- {
- GameObject tempObj = particleObjs[lookLevel];//particleObjs 陣列儲存所有的特效(水晶)物體
- SpriteRenderer[] renderers = tempObj.GetComponentsInChildren<SpriteRenderer>(true);
- for (int i=0;i<renderers.Length;i++)
- {
- ParticObjIsLook(renderers[i].transform);
- }
- }
- public bool ParticObjIsLook(Transform objTrs)
- {
- RaycastHit2D hit2D;
- if (isClimb) //如果進行了爬牆狀態 射線發射方向改變
- {
- if (nowDir == PlayDir.Right)
- {
- hit2D = Physics2D.Raycast(objTrs.position, Vector3.right, boxSize.y, playerLayerMask);
- }
- else
- {
- hit2D = Physics2D.Raycast(objTrs.position, Vector3.left, boxSize.y, playerLayerMask);
- }
- }
- else
- {
- hit2D = Physics2D.Raycast(objTrs.position, Vector3.down, boxSize.y, playerLayerMask);
- }
- if (hit2D.transform!=null)
- {
- objTrs.gameObject.SetActive(true);
- return true;
- }
- objTrs.gameObject.SetActive(false);
- return false;
- }
二段跳特效
二段跳特效也是使用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數值按需調整即可。由於是圓形粒子,跟隨時間的旋轉也可以取消。完成後如下圖:
暗影衝刺粒子效果
然後就是在程式碼中,暗影衝刺開始時生成對應的特效物體,讓特效物體隨玩家進行移動,在暗影衝刺結束時停止跟隨,並在一段時間後銷燬特效物體。程式碼比較簡單,這裡就不在貼出了。
拖尾與回覆動畫
在播放暗影衝刺動畫時,還附帶有拖尾的幀動畫,以及暗影衝刺能量回復的幀動畫。一開始製作好相應的幀動畫物體,並放在玩家的節點下,在衝刺開始以及結束的時候播放對應動畫即可。動畫如下:
回覆與拖尾幀動畫
暗影衝刺動畫
在原作中,暗影衝刺在地上進行衝刺,與在空中進行衝刺略有不用。需要在播放動畫時,進行判斷,此處需要注意!動作如下:
不同的衝刺序列幀
特效物體組合後效果如下:
暗影衝刺特效演示
攻擊互動特效
玩家攻擊到不同的物體將會有不同的特效提示,此處摸一下魚,只製作攻擊碰撞到陷阱的互動特效。
仍然先將特效的幀動畫製作出來。如下:
攻擊互動幀動畫
然後在程式碼中,攻擊檢測時進行生成對應的幀動畫物體。需要注意的是,不同的攻擊方向,生成的物體方向也是不一樣的,程式碼大致如下:
- public void CheckAckInteractive(int dir) //引數為當前的攻擊方向
- {
- float distance = 1.8f; //射線的檢測長度
- RaycastHit2D hit2D = new RaycastHit2D();
- Vector2 raySize = new Vector2(boxSize.x , boxSize.y); //射線的大小
- switch (dir)
- {
- case 1:
- hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.left, distance, playerLayerMask);
- break;
- case 2:
- hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.right, distance, playerLayerMask);
- break;
- case 3:
- hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.up, distance, playerLayerMask);
- break;
- case 4:
- hit2D = Physics2D.BoxCast(transform.position, raySize, 0, Vector2.down, distance, playerLayerMask);
- break;
- }
- if (hit2D.collider != null)
- {
- if (hit2D.collider.gameObject.CompareTag("Trap")) //如果是陷阱就有後坐力
- {
- var tempObj = Instantiate(attactEffectObj, hit2D.point, Quaternion.identity);//攻擊互動特效
- switch (dir)//根據攻擊方向旋轉特效物體
- {
- case 1:
- tempObj.transform.rotation = Quaternion.Euler(new Vector3(0, 0, -90));
- break;
- case 2:
- tempObj.transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90));
- break;
- case 3:
- tempObj.transform.rotation = Quaternion.Euler(new Vector3(0, 0, 180));
- break;
- case 4://預設方向不需要修改
- break;
- }
- }
- }
結語
本系列到了現在專案算是完結了。雖然我漏掉了音效新增以及一些其餘的細節內容,但是完整工程上面其實已經新增上去了對應的內容,需要的童鞋可以下載瞭解。文章後面還會有一個打包後遊戲檔案,歡迎下載試玩。(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
相關文章
- 用Unity重現《空洞騎士》的苦痛之路(1):動作篇Unity
- 用Unity重現《空洞騎士》的苦痛之路(3)——地圖篇Unity地圖
- 用Unity重現《空洞騎士》的苦痛之路(2)——人物控制篇Unity
- Android 專案重構之路:實現篇Android
- 用canvas實現流星特效Canvas特效
- Android 專案重構之路:介面篇Android
- 用jQuery實現翻書特效jQuery特效
- Android 專案重構之路:架構篇Android架構
- 用Unity實現彈反效果Unity
- PAINGATE 苦痛系AI
- 特效實現用查表法實現對水波的模擬(轉)特效
- 用VB實現“百葉窗”的圖形特效 (轉)特效
- 用最簡單的方法實現原生 JS 放大鏡特效JS特效
- 解Bug之路-dubbo應用無法重連zookeeper
- Vue2.0 探索之路——元件複用重複響應的研究Vue元件
- HTML5 Canvas 破碎重組的視訊特效HTMLCanvas特效
- Unity 學員原創滾球聯機遊戲,眾多道具特效大樂鬥如何實現?Unity遊戲特效
- Asp.Net MVC4 系列-- 進階篇之路由(1)ASP.NETMVC路由
- Asp.Net MVC4 系列--進階篇之路由 (2)ASP.NETMVC路由
- 用Unity做個遊戲(十) - 完結篇,內容補全Unity遊戲
- Seata RPC 模組的重構之路RPC
- Unity 中層的運用Unity
- 17 個實用的影像特效庫特效
- .滑鼠點選愛心特效的實現特效
- Openlayers4地圖重複出現的問題地圖
- Houdini在UE4特效中的嘗試分享特效
- 喵的Unity遊戲開發之路 - 推球:遊戲中的物理Unity遊戲開發
- 喵的Unity遊戲開發之路 - 軌道攝像機Unity遊戲開發
- Unity URP 描邊 用RenderPassFeature實現Unity
- Unity應用架構設計(4)——設計可複用的SubView和SubViewModel(Part 1)Unity應用架構View
- 用Flash、HTML5和Unity開發網頁遊戲的現實HTMLUnity網頁遊戲
- 衝擊IPO:達達的負“重”上市之路
- CSS實現開關特效CSS特效
- 直播特效的實現原理與難點特效
- Unity應用架構設計(8)——使用ServiceLocator實現物件的注入Unity應用架構物件
- 用RecyclerView 重寫LayoutManager實現BannerViewView
- 我的WebDesign之路--提高篇[3] (轉)Web
- 我的WebDesign之路--提高篇[1] (轉)Web