Unity3D入门:手把手带你开发一款坦克大战的游戏

Unity3D入门:手把手带你开发一款坦克大战的游戏

首页战争策略坦克大战3D更新时间:2024-04-19

这一次我将带领大家用Unity3D游戏引擎去开发一款游戏——坦克大战。

游戏玩法如下:

游戏演示效果如下:

说明:游戏开发平台:Windows 10、Unity版本:Unity 2017.2.0f3

一、创建游戏工程

按照下图依次点击“New”→“输入工程名”→“选择保存路径”→“点击Create project按钮”

Unity工程创建完成后如图所示:

接下来应该导入此项目所需的Unity Package文件,要用到的Unity package文件大家可以去Unity3D的官方网站下载(地址:https://www.assetstore.unity3d.com/en/?&_ga=2.21331896.203842797.1510021401-332298740.1510021401#!/content/46209/)

导入Package的方法很简单,只需要在“Project”窗口下的“Assets”目录上右键,再依次选择“Import Package”→“Custom Package...”,选中下载好的package文件,然后在弹出的窗口中点击“Import”按钮即可

导入完成后目录结构如下:

二、添加游戏主场景

首先在“Assets”目录下新建一个文件夹“Scenes”,用来存放场景。创建方式如图:右键”Assets“→”Create“→”Folder“

按下快捷键”Ctrl S“保存场景,在目录“Assets”→“Prefabs”下找到预制体“LevelArt”,将它拖入“Hierarchy”窗口中

随后删除“Directional Light”

三、制作坦克和炮弹的预制体

3.1、坦克预制体的制作

在目录“Assets”→“Models”下找到模型“Tank”,将它拖到“Hierarchy”窗口中

在“Tank”上右键选择“Create Empty”,创建一个空的游戏物体“FiringPoint”。将“FiringPoint”用作炮弹的发射点,后续将从此处发射(实例化)炮弹

将“发射点”调整到合适的位置,如下图:

在“Tank”上右键“UI”→“Slider”创建一个滑动条,后续我们将使用这个滑动条作为坦克的血条,用来显示坦克剩余的血量。

定位到“Canvas”中的“Slider”,展开“Slider”滑动条,将下面的“Handle Slide Area”删除

因为我们将要展示的血条是一个环状的图形,所以我们还需改变它的“Background”。

首先找到目录“Assets”→“Sprites”下的“Health Wheel”,然后选中“Slider”下的“Background”,将前面的“Health Wheel”拖入到“Image”组件上的“Source Image”中,以此来改变Slider的背景

重复上述方式,改变“Fill Area”→“Fill”的“Source Image”

改变“Slider”的显示方式,让其居中,并将“Width”和“Height”设为一个合适的值,比如40

然后将“Slider”里面的“Baackground”、“Fill Area”、“Fill”都设置为上下左右填充的方式,并把它们的“Left”、“Right”、“Top”、“Bottom”统统设为零。然后定位到“Fill”,把“Image”组件的“Color”属性修改为血红色,把“Image Type”属性修改为“Filled”

到这一步血环的基本样式就做好了,你可以通过改变“Slider”的“Value”的大小来检测效果,效果如下图:

上述效果完成之后,还需把“Canvas”的“Render Mode”改为“World Space”,并将“Canvas”整体拖入“Tank”下

修改“Slider”的显示,将其改为上下左右填充,修改“Canvas”的“Width”、“Height”,将它们改为合适的大小,比如3.8,将“Canvas”围绕X轴旋转90度,也就是将“Rotation”的“X”改为90,以让其与地面平行,效果如下:

选中游戏物体“Tank”,点击“Inspector”窗口中的“Add Component”按钮搜索并添加“Rigidbody”和“Box Collider”两个组件

然后点击“Edit Collider”按钮编辑碰撞器的大小,让它吻合坦克的大小即可,如下图,编辑坦克上的绿框即可进行调整

至此,坦克的预制体基本制作完毕,别忘了还要将它拖入到“Assets”→“Prefabs”目录下才算彻底完成

3.2、炮弹预制体的制作

同样的,在目录“Assets”→“Models”下找到“Shell”的模型并将其拖放到场景中,然后通过“Inspector”窗口下的“Add Component”按钮添加两个组件,分别是“Rigidbody”和“Capsule Collider”

同样的,通过编辑碰撞器的大小来吻合炮弹的大小这里还要将碰撞器的”Direction“属性改为”Z-Axis“

这样炮弹预制体的制作也结束了,一样的,不要忘了要将”Hierarchy“窗口下的”Shell“拖到目录”Assets“→”Prefabs“下才算完成

四、控制坦克的移动和攻击

我们的游戏有两个玩家,自然就需要两个坦克。前文已经说过,我们将通过”W“、”A“、”S“、”D“键控制玩家1(1号坦克)、通过方向键控制玩家2(2号坦克)。

首先将之前在”Hierarchy“窗口下的”Tank“和”Shell“两个游戏物体删除。随后将目录”Prefabs“下的”Tank“放入场景中,当然需要放入两个,并把它们分别重命名为”Tank1“、”Tank2“。

为了便于区分,我把”Tank1“设成蓝色,把”Tank2“设为红色

展开”Tank1“→”TankRenderers“,分别将其下面的”TankChassis“、”TankTracksLeft“、”TankTracksRight“、”TankTurret“中的”Materials“的属性”Element 0“的值改为目录”Prefabs“→”Materials“下的”Blue“

对”Tank2“重复上述操作,只不过把材料”Blue“替换为”Red“

改完后的整体效果如下:

4.1、控制坦克移动

在控制坦克的移动之前我们稍微进行一下项目设置,因为要让Unity区分”W“、”A“、”S“、”D“键和方向键并做不同的控制。

首先在菜单栏中依次点击”Edit“→”Project Settings“→”Input“

然后在”Inspector“窗口下右键”Axes“→”Horizontal“,再点击”Duplicate Array Element“复制两个”Horizontal“,将复制得到的一个”Horizontal“的”Name“改为”HorizontalPlayer1“并去掉其中的”left“、”right“两个值,因为我们只希望通过”A“、”D“键而不是左右键来控制玩家1的移动(转向);同理将复制得到的另一个”Horizontal“的”Name“改为”HorizontalPlayer2“并去掉其中的”A“、”D“两个值,因为我们只希望通过左右方向键而不是”A“、”D“键来控制玩家2的移动(转向)。

对于”Vertical“重复上面的操作,只不过要把上面的”Horizontal“全部替换为”Vertical“。

给坦克的预制体添加一个脚本组件,将其命名为”TankMovement“。右键此脚本,点击”Edit Script“,编辑脚本文件的内容如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class TankMovement : MonoBehaviour {

private Rigidbody rb;

public int number = 1; // 通过编号区分不同坦克

public float speed = 10; //速度大小

public float angularSpeed = 10; //转向角度

// Use this for initialization

void Start () {

rb = GetComponent<Rigidbody>();

}

// Update is called once per frame

void Update () {

float h = Input.GetAxis("HorizontalPlayer" number);

float v = Input.GetAxis("VerticalPlayer" number);

rb.velocity = transform.forward * v * speed;

rb.angularVelocity = transform.up * h * angularSpeed;

}

}

因为number默认为1,所以需要修改”Tank2“的”Tank Movement“组件下的”Number“属性,将其改为2。

然后需要注意一点,我们还要把”Tank“预制体的”Constraints“下的”Freeze Position“的”Y“给勾选上,把”Freeze Rotation“的”X“、”Z“勾选上

4.2、控制坦克攻击

给坦克的预制体添加一个脚本组件,将其命名为”TankAttack“。右键此脚本,点击”Edit Script“,编辑脚本文件的内容如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class TankAttack : MonoBehaviour {

public Transform firingPointTransform;

public GameObject shellPrefab;

public KeyCode firingKey = KeyCode.Space; // 开火键,默认为空格键

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

if (Input.GetKeyDown(firingKey)) {

Instantiate(shellPrefab, firingPointTransform.position, firingPointTransform.rotation); // 发射炮弹即实例化炮弹

}

}

}

写入以上代码后,别忘了在Unity中给”firingPointTransform“和”shellPrefab“赋值,然后再把”Tank2“的”firingKey“改为回车键。

五、控制炮弹的飞行和爆炸

在”Shell“预制体上添加一个脚本组件,并命名为”Shell“,用来控制炮弹的飞行和爆炸。右键此脚本组件并选择”Edit Script“,编辑脚本的内容如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class Shell : MonoBehaviour {

private Rigidbody rb;

public GameObject shellExplosionPrefab;

public float shellSpeed = 15;

private float duration = 1.50f; // 爆炸动画效果持续时间

// Use this for initialization

void Start () {

rb = GetComponent<Rigidbody>();

}

// Update is called once per frame

void Update () {

rb.velocity = transform.forward * shellSpeed;

}

private void OnCollisionEnter(Collision collision)

{

GameObject shellExplosion = Instantiate(shellExplosionPrefab, transform.position, transform.rotation) as GameObject;

Destroy(gameObject);

Destroy(shellExplosion, duration);

}

}

同样别忘了在Unity中给属性”shellExplosionPrefab“赋值。还要记得把”ShellExplosion“的”Play On Awake“勾选上。这样动画才能播放

六、控制坦克的血量和伤害

首先修改”Shell.cs“脚本的内容如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class Shell : MonoBehaviour {

private Rigidbody rb;

public GameObject shellExplosionPrefab;

public float shellSpeed = 15;

private float duration = 1.50f; // 爆炸动画效果持续时间

// Use this for initialization

void Start () {

rb = GetComponent<Rigidbody>();

}

// Update is called once per frame

void Update () {

rb.velocity = transform.forward * shellSpeed;

}

private void OnCollisionEnter(Collision collision)

{

GameObject shellExplosion = Instantiate(shellExplosionPrefab, transform.position, transform.rotation) as GameObject;

Destroy(gameObject);

Destroy(shellExplosion, duration);

// 如果炮弹攻击到的是坦克,则对此坦克造成伤害

if (collision.collider.tag == "Tank") {

collision.collider.SendMessage("TankDamage");

}

}

}

给坦克的预制体添加一个名为”TankHealth“的脚本组件用来控制坦克的血量,编辑脚本,其内容如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

public class TankHealth : MonoBehaviour {

public float hp = 100; // 坦克默认共有100滴血

private float hpTotal;

public GameObject tankExplosionPrefab;

private float duration = 1.05f;

public Slider slider;

// Use this for initialization

void Start () {

hpTotal = hp;

}

// Update is called once per frame

void Update () {

}

// 坦克受到伤害

private void TankDamage() {

hp -= Random.Range(10, 20);

slider.value = hp / hpTotal;

if (hp <= 0) { // 坦克血量小于0,被干掉了

GameObject tankExplosion = Instantiate(tankExplosionPrefab, transform.position, transform.rotation) as GameObject;

Destroy(gameObject);

Destroy(tankExplosion, duration);

}

}

}

还是那句话,别忘了在Unity中给属性”tankExplosionPrefab“和”slider“赋值。当然”TankExplosion“的”Play On Awake“也要勾选上。

七、控制相机跟随与视野变化

在控制相机”Camera“之前,先把相机的投影方式改为正交投影”Orthographic“,并控制相机视角让其正好同时能观察到两个坦克

7.1、控制相机的跟随

在相机”Main Camera“中添加脚本组件,并将其命名为”FollowTarget“,脚本文件的内容如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class FollowTarget : MonoBehaviour {

public Transform tank1Transform;

public Transform tank2Transform;

private Vector3 offset; // 相机和两坦克的相对位移,保持其不变即可完成相机跟随

// Use this for initialization

void Start () {

offset = transform.position - (tank1Transform.position tank2Transform.position) / 2;

}

// Update is called once per frame

void Update () {

if (tank1Transform == null || tank2Transform == null) return;

transform.position = (tank1Transform.position tank2Transform.position) / 2 offset;

}

}

这里也要注意别忘了给”tank1Transform“和”tank2Transform“这两个属性赋值。

7.2、控制视野范围的变化

再次打开脚本文件”FollowTarget.cs“,修改为如下内容:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class FollowTarget : MonoBehaviour {

public Transform tank1Transform;

public Transform tank2Transform;

private Camera c;

private Vector3 offset; // 相机和两坦克的相对位移,保持其不变即可完成相机跟随

private float viewProportion; // 此视野比例乘两坦克之间的距离即是当前视野大小

// Use this for initialization

void Start () {

c = GetComponent<Camera>();

offset = transform.position - (tank1Transform.position tank2Transform.position) / 2;

viewProportion = c.orthographicSize / Vector3.Distance(tank1Transform.position, tank2Transform.position);

}

// Update is called once per frame

void Update () {

if (tank1Transform == null || tank2Transform == null) return;

transform.position = (tank1Transform.position tank2Transform.position) / 2 offset;

c.orthographicSize = viewProportion * Vector3.Distance(tank1Transform.position, tank2Transform.position);

}

}

将上面内容添加完毕后你会发现,两个坦克会一直处于相机视野的中心,并且视野范围会随着两个坦克之间距离的变化而变化。

八、给游戏添加音效

终于到最后了,在这里我们将给游戏添加音效,让游戏玩起来更带感!

你可以定位到”Assets“→”AudioClips“目录下看一看已经准备好的音乐,有游戏的背景声、坦克的引擎声、炮弹的爆炸声等等,也可以先听一听它的效果

8.1、添加游戏背景音

首先我们来添加背景声,在”Hierarchy“窗口下右键→”Create Empty“创建一个空的游戏物体并命名为”GameManager“

按照下图步骤给”GameManager”添加一个”Audio Source“组件

下面给“Audio Source”设置一个声音源,将“Assets”→“AudioClips”目录下的背景音乐的声音设置为“AudioClip”的值,并将“Play On Awake”和“Loop ”给勾选上。这样背景声就可以循环播放

8.2、给坦克添加引擎声和销毁声

8.2.1、设置引擎声

接下来我们设置坦克引擎的声音,打开脚本“TankMovement.cs”,修改为如下内容:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class TankMovement : MonoBehaviour {

private Rigidbody rb;

public int number = 1; // 通过编号区分不同坦克

public float speed = 10; //速度大小

public float angularSpeed = 10; //转向角度

public AudioClip engineDrivingAudio;

public AudioClip engineIdleAudio;

// Use this for initialization

void Start () {

rb = GetComponent<Rigidbody>();

}

// Update is called once per frame

void Update () {

float h = Input.GetAxis("HorizontalPlayer" number);

float v = Input.GetAxis("VerticalPlayer" number);

rb.velocity = transform.forward * v * speed;

rb.angularVelocity = transform.up * h * angularSpeed;

if (Mathf.Abs(h) > 0.1 || Mathf.Abs(v) > 0.1)

{

AudioSource.PlayClipAtPoint(engineDrivingAudio, transform.position);

}

else {

AudioSource.PlayClipAtPoint(engineIdleAudio, transform.position);

}

}

}

8.2.2、设置销毁声

打开脚本文件“TankHealth.cs”并按如下内容进行修改:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.UI;

public class TankHealth : MonoBehaviour {

public float hp = 100; // 坦克默认共有100滴血

private float hpTotal;

public GameObject tankExplosionPrefab;

private float duration = 1.05f;

public Slider slider;

public AudioClip tankExplosionAudio;

// Use this for initialization

void Start () {

hpTotal = hp;

}

// Update is called once per frame

void Update () {

}

// 坦克受到伤害

private void TankDamage() {

hp -= Random.Range(10, 20);

slider.value = hp / hpTotal;

if (hp <= 0) { // 坦克血量小于0,被干掉了

GameObject tankExplosion = Instantiate(tankExplosionPrefab, transform.position, transform.rotation) as GameObject;

Destroy(gameObject);

Destroy(tankExplosion, duration);

AudioSource.PlayClipAtPoint(tankExplosionAudio, transform.position);

}

}

}

8.3、给炮弹添加声音

8.3.1、设置炮弹的装载声

打开脚本“TankAttack.cs”,将内容修改如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class TankAttack : MonoBehaviour {

public Transform firingPointTransform;

public GameObject shellPrefab;

public KeyCode firingKey = KeyCode.Space; // 开火键,默认为空格键

public AudioClip shotChargingAudio;

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

if (Input.GetKeyDown(firingKey)) {

Instantiate(shellPrefab, firingPointTransform.position, firingPointTransform.rotation); // 发射炮弹即实例化炮弹

AudioSource.PlayClipAtPoint(shotChargingAudio, transform.position);

}

}

}

8.3.2、设置炮弹的开火声和爆炸声

打开脚本文件“Shell.cs”,将内容修改如下:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

public class Shell : MonoBehaviour {

private Rigidbody rb;

public GameObject shellExplosionPrefab;

public float shellSpeed = 15;

private float duration = 1.50f; // 爆炸动画效果持续时间

public AudioClip shellExplosionAudio;

public AudioClip shotFiringAudio;

// Use this for initialization

void Start () {

rb = GetComponent<Rigidbody>();

}

// Update is called once per frame

void Update () {

rb.velocity = transform.forward * shellSpeed;

AudioSource.PlayClipAtPoint(shotFiringAudio, transform.position);

}

private void OnCollisionEnter(Collision collision)

{

GameObject shellExplosion = Instantiate(shellExplosionPrefab, transform.position, transform.rotation) as GameObject;

Destroy(gameObject);

Destroy(shellExplosion, duration);

AudioSource.PlayClipAtPoint(shellExplosionAudio, transform.position);

// 如果炮弹攻击到的是坦克,则对此坦克造成伤害

if (collision.collider.tag == "Tank") {

collision.collider.SendMessage("TankDamage");

}

}

}

到这里音效的设置也算告一段落了,还是要提醒一下别忘了在Unity中给相关的“AudioClip”属性赋值。然后也别忘了保存场景哦。

好了,差不多就这样吧!一个简单的坦克对战的游戏就基本开发完成了,你还可以把该游戏Build到电脑上,劲情享受自己开发的游戏带来的乐趣吧!

--END

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved