說起炸彈超人,相信很多朋友都玩過類似的游戲,其中最為人熟知的莫過于《泡泡堂》。該類型游戲需要玩家在地圖中一邊跑動一邊放置炸彈,同時還要躲避敵方炸彈保護(hù)自己。最初的炸彈超人游戲都是2D的,今天這篇文章將教大家在Unity中實(shí)現(xiàn)一款3D的炸彈超人游戲。
溫馨提示,本教程需要大家了解Unity的基本操作與腳本概念。
下載初始項(xiàng)目資源(請回復(fù)本帖哦~):
davinci8,如果您要查看本帖隱藏內(nèi)容請回復(fù)
準(zhǔn)備工作
將項(xiàng)目初始資源導(dǎo)入Unity項(xiàng)目,資源目錄如下:
其中分別包含要用于游戲的動畫、材質(zhì)、模型、背景音樂、物理材質(zhì)、預(yù)制件、場景、腳本、音效及圖片資源。
放置炸彈
打開項(xiàng)目中的Game場景并運(yùn)行。
可以通過WASD鍵或方向鍵來操作所有角色進(jìn)行移動。下面來讓角色可以放置炸彈。角色1(紅色)通過按下空格鍵來放置炸彈,角色2(藍(lán)色)則通過按下回車鍵進(jìn)行同樣的操作。
打開Player腳本,該腳本負(fù)責(zé)角色所有的移動及動畫邏輯。找到DropBomb函數(shù),添加代碼如下:
[C#] 純文本查看 復(fù)制代碼 /// <summary> /// Drops a bomb beneath the player /// </summary> private void DropBomb() { if (bombPrefab) { //Check if bomb prefab is assigned first // Create new bomb and snap it to a tile Instantiate(bombPrefab, new Vector3(Mathf.RoundToInt(myTransform.position.x), bombPrefab.transform.position.y, Mathf.RoundToInt(myTransform.position.z)), bombPrefab.transform.rotation); } }
其中RoundToInt函數(shù)用于對炸彈的坐標(biāo)參數(shù)四舍五入,以避免炸彈放置位置偏離出地塊中心。
運(yùn)行場景,效果如下:
Bomb代碼中定義的LayerMask用于剔除射線對地塊的檢測,這里還需要在檢視面板中編輯層,并新增用戶層命名為“Blocks”,然后將層級視圖中Blocks游戲?qū)ο蟮腖ayer設(shè)置為“Blocks”。
更改Blocks對象的層級時會跳出提示框,詢問是否更改子節(jié)點(diǎn),選擇是即可:
然后選中Bomb對象,在檢視面板中將Bomb腳本的Level Mask設(shè)為“Blocks”:
連鎖反應(yīng)
如果炸彈炸到了另一個炸彈,那么被炸到的炸彈也會爆炸。Bomb腳本中的OnTriggerEnter
函數(shù)是MonoBehaviour預(yù)定義的函數(shù),會在觸發(fā)器與Rigidbody碰撞之前調(diào)用。這里OnTriggerEnter會檢測被碰撞的炸彈是否是被炸彈特效所碰撞,如果是,則該炸彈也要爆炸。
現(xiàn)在運(yùn)行場景,效果如下:
判定游戲結(jié)果
打開Player腳本,添加下面的代碼:
[C#] 純文本查看 復(fù)制代碼 //Manager public GlobalStateManager GlobalManager; //Player parameters [Range(1, 2)] //Enables a nifty slider in the editor public int playerNumber = 1; //Indicates what player this is: P1 or P2 public float moveSpeed = 5f; public bool canDropBombs = true; //Can the player drop bombs? public bool canMove = true; //Can the player move? public bool dead = false; //Is this player dead?
其中GlobalManager是GlobalStateManager腳本的引用,該腳本用于通知玩家獲勝或死亡的消息。dead則用于標(biāo)志玩家是否死亡。
更改OnTriggerEnter函數(shù)代碼如下:
[C#] 純文本查看 復(fù)制代碼 public void OnTriggerEnter(Collider other) { if (!dead other.CompareTag(Explosion)) { //Not dead hit by explosion Debug.Log(P + playerNumber + hit by explosion!); dead = true; GlobalManager.PlayerDied(playerNumber); //Notify global state manager that this player died Destroy(gameObject); } }
該函數(shù)作用為設(shè)置dead變量來通知玩家死亡,并告知全局狀態(tài)管理器玩家的死亡信息,然后銷毀玩家對象。
在檢視面板中選中兩個玩家對象,將Global State Manager游戲?qū)ο筚x值給Player腳本的Global Manger字段。
再次運(yùn)行場景,效果如下:
打開GlobalStateManager腳本,添加以下代碼:
[C#] 純文本查看 復(fù)制代碼 public List<GameObject> Players = new List<GameObject>(); private int deadPlayers = 0; private int deadPlayerNumber = -1; public void PlayerDied(int playerNumber) { deadPlayers++; if (deadPlayers == 1) { deadPlayerNumber = playerNumber; Invoke(CheckPlayersDeath, .3f); } }
其中deadPlayers表示死亡的玩家數(shù)量,deadPlayerNumber則用于記錄死亡玩家的編號。PlayerDied函數(shù)用于添加死亡玩家,并設(shè)置deadPlayerNumber屬性,在0.3秒后檢測另一位玩家是否也死亡。
然后在腳本中添加CheckPlayersDeath函數(shù),代碼如下:
[C#] 純文本查看 復(fù)制代碼 void CheckPlayersDeath() { if (deadPlayers == 1) { //Single dead player, hes the winner if (deadPlayerNumber == 1) { //P1 dead, P2 is the winner Debug.Log(Player 2 is the winner!); } else { //P2 dead, P1 is the winner Debug.Log(Player 1 is the winner!); } } else { //Multiple dead players, its a draw Debug.Log(The game ended in a draw!); } }
以上代碼用于判斷哪位玩家獲得勝利,如果兩位玩家均死亡,則打成平局。
運(yùn)行場景,效果如下:
總結(jié)
到此本篇教程就結(jié)束了,大家還可以在此基礎(chǔ)上對該項(xiàng)目進(jìn)行擴(kuò)展,例如添加“推箱子”功能,將位于自己腳邊的炸彈推給敵方,或是限制能夠放置的炸彈數(shù)量,添加快速重新開始游戲的界面,設(shè)置可以被炸彈炸毀的障礙物,設(shè)置一些道具用于獲得炸彈或者增加生命值,還可以增加多人對戰(zhàn)模式與朋友一起變身炸彈超人等等。大家都來發(fā)揮自己的創(chuàng)意吧!
下載完整示例工程(請回復(fù)本帖哦~):
davinci8,如果您要查看本帖隱藏內(nèi)容請回復(fù)
原文鏈接:https://www.raywenderlich.com/125559/make-game-like-bomberman
原作者:Eric Van de Kerckhove
轉(zhuǎn)載請注明來自Unity官方中文社區(qū) Unity, 炸彈超人, 泡泡堂, 教程
銳亞教育 銳亞科技 unity unity教程
-
棒(0) 回復(fù) (0)