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

其中分别包含要用于游戏的动画、材质、模型、背景音乐、物理材质、预制件、场景、脚本、音效及图片资源。
放置炸弹
打开项目中的Game场景并运行。

可以通过WASD键或方向键来操作所有角色进行移动。下面来让角色可以放置炸弹。角色1(红色)通过按下空格键来放置炸弹,角色2(蓝色)则通过按下回车键进行同样的操作。
打开Player脚本,该脚本负责角色所有的移动及动画逻辑。找到DropBomb函数,添加代码如下:
/// <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函数用于对炸弹的坐标参数四舍五入,以避免炸弹放置位置偏离出地块中心。

运行场景,效果如下:

创建爆炸效果
在Scripts文件夹下新建C#脚本命名为Bomb:

找到Prefabs文件夹下的Bomb预制件,将Bomb脚本绑定到该游戏对象上。然后打开Bomb脚本,添加代码如下:
using UnityEngine;
using System.Collections;
using System.Runtime.CompilerServices; public class Bomb : MonoBehaviour {
public AudioClip explosionSound;
public GameObject explosionPrefab;
public LayerMask levelMask; // This LayerMask makes sure the rays cast to check for free spaces only hits the blocks in the level
private bool exploded = false; // Use this for initialization
void Start() {
Invoke("Explode", 3f); //Call Explode in 3 seconds
} void Explode() {
//Explosion sound
AudioSource.PlayClipAtPoint(explosionSound,transform.position); //Create a first explosion at the bomb position
Instantiate(explosionPrefab, transform.position, Quaternion.identity); //For every direction, start a chain of explosions
StartCoroutine(CreateExplosions(Vector3.forward));
StartCoroutine(CreateExplosions(Vector3.right));
StartCoroutine(CreateExplosions(Vector3.back));
StartCoroutine(CreateExplosions(Vector3.left)); GetComponent<MeshRenderer>().enabled = false; //Disable mesh
exploded = true;
transform.FindChild("Collider").gameObject.SetActive(false); //Disable the collider
Destroy(gameObject,.3f); //Destroy the actual bomb in 0.3 seconds, after all coroutines have finished
} public void OnTriggerEnter(Collider other) {
if (!exploded && other.CompareTag("Explosion")) { //If not exploded yet and this bomb is hit by an explosion...
CancelInvoke("Explode"); //Cancel the already called Explode, else the bomb might explode twice
Explode(); //Finally, explode!
}
} private IEnumerator CreateExplosions(Vector3 direction) {
for (int i = ; i < ; i++) { //The 3 here dictates how far the raycasts will check, in this case 3 tiles far
RaycastHit hit; //Holds all information about what the raycast hits Physics.Raycast(transform.position + new Vector3(,.5f,), 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 if (!hit.collider) { // Free space, make a new explosion
Instantiate(explosionPrefab, transform.position + (i * direction), explosionPrefab.transform.rotation);
}
else { //Hit a block, stop spawning in this direction
break;
} yield return new WaitForSeconds(.05f); //Wait 50 milliseconds before checking the next location
} }
}
在检视面板中,将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脚本,添加下面的代码:
//Manager
public GlobalStateManager GlobalManager; //Player parameters
[Range(, )] //Enables a nifty slider in the editor
public int playerNumber = ; //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则用于标志玩家是否死亡。
更改OnTriggerEnter函数代码如下:
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);
}
}
该函数作用为设置dead变量来通知玩家死亡,并告知全局状态管理器玩家的死亡信息,然后销毁玩家对象。
在检视面板中选中两个玩家对象,将Global State Manager游戏对象赋值给Player脚本的Global Manger字段。

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

打开GlobalStateManager脚本,添加以下代码:
public List<GameObject> Players = new List<GameObject>(); private int deadPlayers = ;
private int deadPlayerNumber = -; public void PlayerDied(int playerNumber) {
deadPlayers++; if (deadPlayers == ) {
deadPlayerNumber = playerNumber;
Invoke("CheckPlayersDeath", .3f);
}
}
以上代码用于判断哪位玩家获得胜利,如果两位玩家均死亡,则打成平局。
运行场景,效果如下:

总结
到此本篇教程就结束了,大家还可以在此基础上对该项目进行扩展,例如添加“推箱子”功能,将位于自己脚边的炸弹推给敌方,或是限制能够放置的炸弹数量,添加快速重新开始游戏的界面,设置可以被炸弹炸毁的障碍物,设置一些道具用于获得炸弹或者增加生命值,还可以增加多人对战模式与朋友一起变身炸弹超人等等。大家都来发挥自己的创意吧!
文章来自:http://forum.china.unity3d.com/thread-24404-1-1.html
原文链接:https://www.raywenderlich.com/125559/make-game-like-bomberman
原作者:Eric Van de Kerckhove
制作一款3D炸弹超人游戏的更多相关文章
- 如何制作一款HTML5 RPG游戏引擎——第五篇,人物&人物特效
上一次,我们实现了对话类,今天就来做一个游戏中必不可少的——人物类. 当然,你完全是可以自己写一个人物类,但是为了方便起见,还是决定把人物类封装到这个引擎里. 为了使这个类更有意义,我还给人物类加了几 ...
- 如何制作一款HTML5 RPG游戏引擎——第四篇,情景对话
今天我们来实现情景对话.这是一个重要的功能,没有它,游戏将变得索然无味.所以我们不得不来完成它. 但是要知道,使用对话可不是一件简单的事,因为它内部的东西很多,比如说人物头像,人物名称,对话内容... ...
- 如何制作一款HTML5 RPG游戏引擎——第三篇,利用幕布切换场景
开言: 在RPG游戏中,如果有地图切换的地方,通常就会使用幕布效果.所谓的幕布其实就是将两个矩形合拢,直到把屏幕遮住,然后再展开直到两个矩形全部移出屏幕. 为了大家做游戏方便,于是我给这个引擎加了这么 ...
- 如何制作一款HTML5 RPG游戏引擎——第二篇,烟雨+飞雪效果
今天我们来实现烟雨+飞雪效果.首先来说,一款经典的RPG游戏难免需要加入天气的变化.那么为了使我们的RPG游戏引擎更完美,我们就只好慢慢地实现它. 本文为该系列文章的第二篇,如果想了解以前的文章可以看 ...
- 用Html5结合Qt制作一款本地化EXE游戏-太空大战(Space War)
本次来说一说如何利用lufylegend.js引擎制作一款html5游戏后将其通过Qt转换成EXE程序.步骤其实非常简单,接下来就一步步地做一下解释和说明. 首先我们来开发一个有点类似于太空大战的游戏 ...
- 如何制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现
一,话说天下大事 前不久看到lufy的博客上,有一位朋友想要一个RPG游戏引擎,出于兴趣准备动手做一做.由于我研究lufylegend有一段时间了,对它有一定的依赖性,因此就准备将这个引擎基于lufy ...
- 3D跑酷游戏《月影忍者之疾风狂逃》
<月影忍者之疾风狂逃>是一款3D跑酷游戏,也是我实习的时候参与的一个项目,在那个公司我学到了很多东西,谢谢他们.大家可以去玩玩这个游戏啊,还是不错的哦.
- 张瀚荣:如何用UE4制作3D动作游戏
转自:http://www.gamelook.com.cn/2015/06/218267 GameLook报道/ 6月5日,2015年第三期GameLook开放日‧虚幻引擎专场活动在上海正式举行,此次 ...
- 基于html5制作3D拳击游戏源码下载
今天给大家分享一款基于HTML5实现的3d拳王游戏源码.这款实例适用浏览器:360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗. 不支持IE8及以下浏览器. 在线预览 ...
随机推荐
- 【Android】8.4 让主题自适应不同的Android版本
分类:C#.Android.VS2015: 创建日期:2016-02-17 一.简介 默认情况下,高版本提供的主题不能在低版本的Android系统上运行.但是,通过自定义主题,可以让你的系统自适应各自 ...
- Android App 内存泄露之调试工具(1)
Android App 内存泄露之工具(1) 使用内存监測工具 DDMS –> Heap 操作步骤 启动eclipse后,切换到DDMS透视图,并确认Devices视图.Heap视图都是打开的, ...
- 黑客编程教程(十三)多线程DOS程序
DOS基本原理相信大家都已经很熟悉了,DOS工具大家也用的很熟悉.在群里 经常有人说什么时候去DOS什么东西. 现在我们就自己编写一个DOS工具. #include <winsock2.h> ...
- angular学习笔记(二十四)-$http(2)-设置http请求头
1. angular默认的请求头: 其中,Accept 和 X-Requested-With是$http自带的默认配置 Accept:application/json,text/plain ...
- Cocos2d-x Scene生命周期 pushScene和replaceScene
最近在开发过程中遇到很多切换场景的时候概率性崩溃,内存暴增的问题.因此总结一些开发中需要注意的要点, 1. 切换全屏场景的时候最好使用replaceScene而不是pushScene. 因为pushS ...
- 李洪强iOS开发之-FMDB的用法
// // ViewController.m // 04 - FMDB的用法 // // Created by 李洪强 on 2017/6/6. // Copyright © 2017年 李洪 ...
- 07、在 Windows10 上获得屏幕分辨率
因为在 win10 上,app 在运行的时候,默认不是占满全屏幕,并且 windows runtime 当前没有提供获取 屏幕尺寸的 api.在桌面 win32 api 中,可以获取屏幕尺寸,不过因为 ...
- J2EE的13个规范总结
转载自:http://blog.csdn.net/zhuanzhe117/article/details/38763483 什么是J2EE? 在企业级应用中,都有一些通用企业需求模块,如数据库连接,邮 ...
- 由sqlite在手机上的存储位置,引发的onCreate在哪里执行的小结
我们都知道,android为了操作数据库,一般是继承SQLiteOpenHelper类,并实现他的三个函数. 如下所示: package jz.his.db; import android.conte ...
- 创建一个动态链接库 (DLL),使用VS2010
在本演练中,您将创建一个动态链接库 (DLL),其中包含可供其他应用程序使用的有用例程.使用 DLL 是一种重用代码的绝佳方式.您不必在自己创建的每个程序中重新实现这些例程,而只需对这些例程编写一次, ...