制作一款3D炸弹超人游戏

说起炸弹超人,相信很多朋友都玩过类似的游戏,其中最为人熟知的莫过于《泡泡堂》。该类型游戏需要玩家在地图中一边跑动一边放置炸弹,同时还要躲避敌方炸弹保护自己。最初的炸弹超人游戏都是2D的,今天这篇文章将教大家在Unity中实现一款3D的炸弹超人游戏。

准备工作

将项目初始资源导入Unity项目,资源目录如下:



其中分别包含要用于游戏的动画、材质、模型、背景音乐、物理材质、预制件、场景、脚本、音效及图片资源。

放置炸弹

打开项目中的Game场景并运行。



可以通过WASD键或方向键来操作所有角色进行移动。下面来让角色可以放置炸弹。角色1(红色)通过按下空格键来放置炸弹,角色2(蓝色)则通过按下回车键进行同样的操作。

打开Player脚本,该脚本负责角色所有的移动及动画逻辑。找到DropBomb函数,添加代码如下:

 1 /// <summary>
 2 /// Drops a bomb beneath the player
 3 /// </summary>
 4 private void DropBomb() {
 5     if (bombPrefab) { //Check if bomb prefab is assigned first
 6         // Create new bomb and snap it to a tile
 7         Instantiate(bombPrefab,
 8             new Vector3(Mathf.RoundToInt(myTransform.position.x), bombPrefab.transform.position.y, Mathf.RoundToInt(myTransform.position.z)),
 9             bombPrefab.transform.rotation);
10     }
11 }

其中RoundToInt函数用于对炸弹的坐标参数四舍五入,以避免炸弹放置位置偏离出地块中心。



运行场景,效果如下:



创建爆炸效果

在Scripts文件夹下新建C#脚本命名为Bomb:



找到Prefabs文件夹下的Bomb预制件,将Bomb脚本绑定到该游戏对象上。然后打开Bomb脚本,添加代码如下:

 1 using UnityEngine;
 2 using System.Collections;
 3 using System.Runtime.CompilerServices;
 4  
 5 public class Bomb : MonoBehaviour {
 6     public AudioClip explosionSound;
 7     public GameObject explosionPrefab; 
 8     public LayerMask levelMask; // This LayerMask makes sure the rays cast to check for free spaces only hits the blocks in the level
 9     private bool exploded = false;
10  
11     // Use this for initialization
12     void Start() {
13         Invoke("Explode", 3f); //Call Explode in 3 seconds
14     }
15  
16     void Explode() {
17         //Explosion sound
18         AudioSource.PlayClipAtPoint(explosionSound,transform.position);
19  
20         //Create a first explosion at the bomb position
21         Instantiate(explosionPrefab, transform.position, Quaternion.identity);
22  
23         //For every direction, start a chain of explosions
24         StartCoroutine(CreateExplosions(Vector3.forward));
25         StartCoroutine(CreateExplosions(Vector3.right));
26         StartCoroutine(CreateExplosions(Vector3.back));
27         StartCoroutine(CreateExplosions(Vector3.left));
28  
29         GetComponent<MeshRenderer>().enabled = false; //Disable mesh
30         exploded = true; 
31         transform.FindChild("Collider").gameObject.SetActive(false); //Disable the collider
32         Destroy(gameObject,.3f); //Destroy the actual bomb in 0.3 seconds, after all coroutines have finished
33     }
34  
35     public void OnTriggerEnter(Collider other) {
36         if (!exploded && other.CompareTag("Explosion")) { //If not exploded yet and this bomb is hit by an explosion...
37             CancelInvoke("Explode"); //Cancel the already called Explode, else the bomb might explode twice 
38             Explode(); //Finally, explode!
39         }
40     }
41  
42     private IEnumerator CreateExplosions(Vector3 direction) {
43         for (int i = 1; i < 3; i++) { //The 3 here dictates how far the raycasts will check, in this case 3 tiles far
44             RaycastHit hit; //Holds all information about what the raycast hits
45  
46             Physics.Raycast(transform.position + new Vector3(0,.5f,0), direction, out hit, i, levelMask); //Raycast in the specified direction at i distance, because of the layer mask it'll only hit blocks, not players or bombs
47  
48             if (!hit.collider) { // Free space, make a new explosion
49                 Instantiate(explosionPrefab, transform.position + (i * direction), explosionPrefab.transform.rotation);
50             }
51             else { //Hit a block, stop spawning in this direction
52                 break;
53             }
54  
55             yield return new WaitForSeconds(.05f); //Wait 50 milliseconds before checking the next location
56         }
57  
58     }
59 }

在检视面板中,将Bomb预制件赋值给脚本的Explosion Prefab属性,该属性用于定义需要生成爆炸效果的对象。Bomb脚本使用了协程来实现爆炸的效果,StartCoroutine函数将朝着4个方向调用CreateExplosions函数,该函数用于生成爆炸效果,在For循环内遍历炸弹能够炸到的所有单元,然后为能够被炸弹影响的各个单元生成爆炸特效,炸弹对墙壁是没有伤害的。最后,在进入下一次循环前等待0.05秒。

代码作用类似下图:



红线就是Raycast,它会检测炸弹周围的单元是否为空,如果是,则朝着该方向生成爆炸效果。如果碰撞到墙,则不生成爆炸并停止检测该方向。所以前面需要让炸弹在地块中心生成,负责就会出现不太理想的效果:



Bomb代码中定义的LayerMask用于剔除射线对地块的检测,这里还需要在检视面板中编辑层,并新增用户层命名为“Blocks”,然后将层级视图中Blocks游戏对象的Layer设置为“Blocks”。



更改Blocks对象的层级时会跳出提示框,询问是否更改子节点,选择是即可:



然后选中Bomb对象,在检视面板中将Bomb脚本的Level Mask设为“Blocks”:



连锁反应

如果炸弹炸到了另一个炸弹,那么被炸到的炸弹也会爆炸。Bomb脚本中的OnTriggerEnter
函数是MonoBehaviour预定义的函数,会在触发器与Rigidbody碰撞之前调用。这里OnTriggerEnter会检测被碰撞的炸弹是否是被炸弹特效所碰撞,如果是,则该炸弹也要爆炸。

现在运行场景,效果如下:



判定游戏结果

打开Player脚本,添加下面的代码:

 1 //Manager
 2   public GlobalStateManager GlobalManager;
 3  
 4   //Player parameters
 5   [Range(1, 2)] //Enables a nifty slider in the editor
 6   public int playerNumber = 1; //Indicates what player this is: P1 or P2
 7   public float moveSpeed = 5f;
 8   public bool canDropBombs = true; //Can the player drop bombs?
 9   public bool canMove = true; //Can the player move?
10   public bool dead = false; //Is this player dead?

其中GlobalManager是GlobalStateManager脚本的引用,该脚本用于通知玩家获胜或死亡的消息。dead则用于标志玩家是否死亡。

更改OnTriggerEnter函数代码如下:

1 public void OnTriggerEnter(Collider other) {
2     if (!dead && other.CompareTag("Explosion")) { //Not dead & hit by explosion
3         Debug.Log("P" + playerNumber + " hit by explosion!");
4  
5         dead = true;
6         GlobalManager.PlayerDied(playerNumber); //Notify global state manager that this player died
7         Destroy(gameObject);
8     }
9 }

该函数作用为设置dead变量来通知玩家死亡,并告知全局状态管理器玩家的死亡信息,然后销毁玩家对象。

在检视面板中选中两个玩家对象,将Global State Manager游戏对象赋值给Player脚本的Global Manger字段。



再次运行场景,效果如下:



打开GlobalStateManager脚本,添加以下代码:

 1 public List<GameObject> Players = new List<GameObject>();
 2  
 3  private int deadPlayers = 0;
 4  private int deadPlayerNumber = -1;
 5  
 6  public void PlayerDied(int playerNumber) {
 7      deadPlayers++;
 8  
 9      if (deadPlayers == 1) {
10          deadPlayerNumber = playerNumber;
11          Invoke("CheckPlayersDeath", .3f);
12      }
13  }

以上代码用于判断哪位玩家获得胜利,如果两位玩家均死亡,则打成平局。

运行场景,效果如下:



总结

到此本篇教程就结束了,大家还可以在此基础上对该项目进行扩展,例如添加“推箱子”功能,将位于自己脚边的炸弹推给敌方,或是限制能够放置的炸弹数量,添加快速重新开始游戏的界面,设置可以被炸弹炸毁的障碍物,设置一些道具用于获得炸弹或者增加生命值,还可以增加多人对战模式与朋友一起变身炸弹超人等等。大家都来发挥自己的创意吧!

文章来自:http://forum.china.unity3d.com/thread-24404-1-1.html

原文链接:https://www.raywenderlich.com/125559/make-game-like-bomberman
原作者:Eric Van de Kerckhove

转载于:https://www.cnblogs.com/AaronBlogs/p/7039772.html

Unity是一款跨平台的游戏开发引擎,可以用来制作各种类型的游戏,包括3D炸弹人。 首先,我们需要使用Unity的3D建模工具来创建炸弹人的角色模型。我们可以使用简单的几何图形,如立方体和球体,来构建角色的身体、头部、四肢等部分。然后,我们可以为角色添加纹理和材质,使其看起来更加逼真。 接下来,我们需要为炸弹人添加动画。Unity提供了强大的动画制作工具,可以使角色能够行走、跳跃、爆炸等。我们可以使用关键帧动画或骨骼动画来实现这些动作,从而让角色在游戏中能够有生动的表现。 然后,我们需要创建游戏的场景。可以使用Unity提供的场景编辑器,通过添加地图和障碍物来设计游戏背景。我们可以设置每个障碍物的属性,如是否可以被炸毁、是否可以被穿过等。 接着,我们需要为游戏添加一些规则和机制。例如,当炸弹人触碰到炸弹时会触发爆炸,炸弹的爆炸范围内的障碍物会被摧毁,等等。通过使用Unity的脚本编程功能,我们可以为角色和物体添加交互逻辑,从而让游戏更加有趣和挑战。 最后,我们需要为游戏增加音效和背景音乐,以及一些界面和用户操作的元素。可以使用Unity的音频编辑器来添加音效,通过添加按钮、计分牌等UI元素来增强游戏的可玩性。 总之,利用Unity制作3D炸弹人需要进行模型建立、动画制作、场景设计、脚本编程以及音效等方面的工作,但凭借Unity强大的功能和友好的用户界面,我们可以相对容易地完成这个任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值