用Unity重現《空洞騎士》的苦痛之路(3)——地圖篇
前言:
大家好。蟲蟲大冒險(?)新的一期又雙叒叕來了。
本期文章主要講解《空洞騎士中》的地圖搭建相關的內容,並會寫一個簡單的相機指令碼。除此之外,還會涉及到如何製作背景、產生異於玩家移動的動態效果。好了,閒話不多說,直接開始。
地圖模板
工欲善其事,必先利其器。在開始地圖搭建之前,我們先製作好遊戲需要的地圖模板,這樣在後續的地圖搭建環節中可省去大量的時間與精力。
如何搭建地圖模板就不多說了,通過圖片資源對比實際遊戲畫面,然後再組合即可。大約有以下幾種主要的模板:
多個小圖拼接的地圖模板
值得注意的是,地面與牆壁的柱子形狀的物體的紋理重複使用,是需要在精靈圖片屬性中編輯九宮格,並在SpriteRender-DrawMode中設定為Tiled,並調整引數才能夠有正確的紋理重複的效果。如下:
設定圖片九宮格相關屬性
這塊技巧在使用Unity製作UI時會頻繁用到,無論什麼遊戲。沒接觸過的童鞋可以留心一下。
由於機關陷阱物體是可以移動的,因而我們還需要寫一個簡單的機關移動指令碼,來控制陷阱的移動。主要邏輯是:先獲取陷阱能夠到達的最上方點與最下方點,然後讓陷阱在其中來回移動。其實現程式碼如下:
- public enum TrapMoveDir
- {
- None,
- Down,
- Up,
- }
- public float moveSpeed;//移動速度
- public bool isMove=true;//是否進行移動
- public Transform startTrans;//開始的點
- public Transform endTrans;//結束的點
- public Transform trapObj;//陷阱物體
- TrapMoveDir moveDir;//移動方向列舉
- public void TrapMove()
- {
- if (moveDir == TrapMoveDir.Down)
- {
- trapObj.transform.position += transform.up* moveSpeed * Time.deltaTime*-1;//朝下移動
- float distance = Vector3.Distance(trapObj.transform.position, startTrans.position);
- if (distance<0.5f)//如果現在距離最下面的點小於0.5f,重新設定移動方向
- {
- moveDir = TrapMoveDir.Up;
- }
- }
- else if (moveDir == TrapMoveDir.Up)
- {
- trapObj.transform.position += transform.up * moveSpeed * Time.deltaTime;
- float distance = Vector3.Distance(trapObj.transform.position, endTrans.position);
- if (distance < 0.5f)
- {
- moveDir = TrapMoveDir.Down;
- }
- }
- }
地圖分層
為了實現原版遊戲中景深的效果,我們需要正確的利用SpriteRender中提供的層級功能(Sorting Layer或者使用Order in Layer),以製作出想要的效果。其中主要的層級分佈大致如下:(PS:原版遊戲中的層級遠遠超出下面列舉的這幾種,這裡只是簡化版)
大致層級圖
優先順序從上到下排列,最上面的的優先順序最高。其中第一層半透明白色遮罩的主要效果,是用於模糊背景物體,產生人物與場景深度不一致的效果。對比如下:
遮罩效果
第二層的白色半透明遮罩主要用於模糊黑色背景,讓黑色背景跟後面的天空配色不產生衝突。
地圖搭建
在開始搭建地圖之前,推薦自己先畫一個地圖草圖,然後按照草圖進行搭建。搭建的時候可能不會跟草圖一摸一樣,但總是比毫無目標的亂搭一氣好得多。如果你是想做到完全跟原版一樣,那麼這一步你就可以跳過了。類似如下:
接下來就是按照草圖,選擇合適的地圖模板和對應的圖片搭建地圖了。其中為了實現荊棘地形散亂生長的感覺,沒有製作對應地形的模板,而是根據周圍環境手動調整荊棘圖片的旋轉縮放引數來實現相應的效果。
而地圖中窗戶的效果就需要花點心思來實現了。首先需要設定好需要通過窗戶才能夠看見的物體的層級,然後還需要新增比視窗物體層級小的黑色遮罩,來遮擋住其餘不需要被檢視的部分。如下:
地圖互動
關於玩家與地圖之間的互動,此處就利用碰撞體的Tag屬性,來進行不同的互動效果的觸發。如下圖:
標籤對應圖
程式碼比較簡單,就是獲取碰撞物體的標籤來執行不同的函式,就不貼出了。
簡易相機
到了這一步,地圖、玩家都準備好了。只需要一個相機遊戲就可以試玩了。
現在我們來寫一個簡單的相機控制指令碼。由於我們是2D遊戲,可以忽略Z軸上的位移來進行相機的移動控制,於是我們的相機的控制原理如下:
相機移動原理
其實現程式碼如下:
- public Transform player; //玩家
- Camera playerCamera; //主相機
- Vector2 boxSize; //視野範圍
- public bool cameraMove;
- public void FollowPlayer()
- {
- Vector3 targetPos = new Vector3(player.position.x, player.position.y, transform.position.z);
- transform.position = Vector3.Lerp(transform.position, targetPos, 0.08f);//插值進行移動
- float distance = Vector3.Distance(targetPos,transform.position);
- if (distance<0.5f)//距離小於0.5f時 停止移動
- {
- cameraMove = false;
- }
- }
- public void CheckBoundary()
- {
- float leftDistance = 0; //左右距離
- if (player.position.x < transform.position.x) //在左邊
- {
- leftDistance = transform.position.x - player.position.x;
- }
- else
- {
- leftDistance = player.position.x - transform.position.x;
- }
- if (leftDistance > boxSize.x * 0.5f)//如果左右距離大於設定好的矩形寬度的一半
- {
- cameraMove = true;//相機開始移動
- }
- float uDDistance = 0; //上下距離
- if (player.position.y < transform.position.y)
- {
- uDDistance = transform.position.y - player.position.y;
- }
- else
- {
- uDDistance = player.position.y - transform.position.y;
- }
- if (uDDistance > boxSize.y * 0.5f)
- {
- cameraMove = true;
- }
- }
背景移動
在現實世界中,人移動時肉眼看遠方,遠處的物體總是移動的比自己慢。而我們就是需要模擬這種特性,來完善我們的景深效果。
實現原理:遊戲一開始獲取玩家的位置並儲存,然後每一幀計算出玩家已經移動的距離,然後使用計算出來的移動位移,來計算出背景此時的座標。程式碼如下:
- public Transform player;
- Vector3 backStartPoint; //初始背景的位置
- Vector3 playeStartPoint; //初始玩家的位置
- public void BackMoveFunc()
- {
- float tempX = player.position.x - playeStartPoint.x;
- float tempY = player.position.y - playeStartPoint.y; //計算X,Y兩軸的歷史位移
- float xVaule = tempX * 0.08f;
- float yVaule = tempY * 0.06f;//計算出背景的X,Y軸位移
- tra
這裡只讓一層的背景進行移動,如果想要更好的效果,可以多加幾層,使移動的速度不同,這樣的效果將會更加逼真。
演示
敲黑板,專案到了這終於算能夠拿出來瞅瞅了,下面就是現在的演示:(在原文觀看)
結語
新的一期又肝完了。雖然通過這個專案我知道櫻桃遊戲工作室將會比我更肝,但我還是想說:快,馬上,趕緊,quick,哈壓庫,把絲之歌交出來。沒有絲之歌玩我要死了啊。
最後再多說一句。遊戲中還有許多小物體上都是有幀動畫的,包括不限於血條,燈光,陷阱等等。如果你的身體機能滿足下圖:
可以考慮全都要。(咕咕咕)
工程下載連結
連結:https://pan.baidu.com/s/1DD2_yJh-rulqpNgIDAuZjA提取碼:7gw1
相關連結,很(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/60295559
相關文章
- 用Unity重現《空洞騎士》的苦痛之路(4)——特效篇Unity特效
- 用Unity重現《空洞騎士》的苦痛之路(1):動作篇Unity
- 用Unity重現《空洞騎士》的苦痛之路(2)——人物控制篇Unity
- Unity3D實現地圖編輯器的外掛Unity3D地圖
- Android 專案重構之路:實現篇Android
- vue地圖視覺化 ArcGIS篇(3)Vue地圖視覺化
- 3倍+提升,高德地圖極致效能優化之路地圖優化
- Openlayers4地圖重複出現的問題地圖
- 3倍+提升,高德地圖極致效能最佳化之路地圖
- 開放世界關卡設計:《空洞騎士》的奧祕,2D地圖如何實現探索感?地圖
- android ---------高德地圖實現定位和3D地圖顯示Android地圖3D
- 百度地圖總結第四篇之路線規劃功能地圖
- 【unity 技術教程】自動>手動 用隨機地圖豐滿你的遊戲Unity隨機地圖遊戲
- 我的WebDesign之路--提高篇[3] (轉)Web
- Android 百度地圖InfoWindow 出現重疊的問題Android地圖
- Android 專案重構之路:介面篇Android
- 騰訊地圖實現地圖找房功能地圖
- Android 專案重構之路:架構篇Android架構
- 深圳3D地圖3D地圖
- 前端效能優化之路——圖片篇。前端優化
- Unity3D如何有效地組織程式碼?Unity3D
- HT for Web整合OpenLayers實現GIS地圖應用Web地圖
- vue地圖視覺化 Cesium篇Vue地圖視覺化
- 高德地圖系列web篇——目的地公交導航地圖Web
- three.js+vue3三維地圖下鑽地圖,實現下鑽全國-》省份-》城市-》區縣JSVue地圖
- 3D地圖折射功能3D地圖
- 地圖採集車的那些事 | 載車篇地圖
- Unity3D熱更新全書-重頭再來Unity3D
- 用HMS Core地圖服務自定義地圖樣式,給你的應用製作專屬個性化地圖地圖
- 用Unity實現彈反效果Unity
- 用unity3d+cardboard開發一個全景圖片檢視器Unity3D
- 【Unity3D】Unity3d打包APK出現的問題—無法找到tool.jarUnity3DAPKJAR
- 高德地圖定位實現地圖
- PAINGATE 苦痛系AI
- Unity3D開發入門教程(四)——用Lua實現元件Unity3D元件
- Unity3d 應用系統分析Unity3D
- Unity使用TextMeshPro實現聊天圖文混排Unity
- ECharts 實現地圖散點圖(上)Echarts地圖