unity3d实战c#语言编写坦克大战游戏
unity3d 坦克大战实战
来源:siki学院-unity3d 坦克大战实战
资源包:https://pan.baidu.com/s/17Ei5tZcDaKO1VlG4AzDc-A
密码:ytnc
1、场景设置
图片展示
在开始时,设置Lighting Settings中的Scene场景的自动渲染功能取消,这样会节省时间,一般发布时再渲染。
同时渲染场景,将图中颜色映射到整个场景中
渲染后的效果如图所示:
再Main camera中选择正交视野
2、控制坦克的前后左右移动
- 给坦克添加冒烟的特效:
在Prefabs中有DustTrail就是冒烟特效,将特效用Ctrl+D复制一份,分别拖到履带下
- 给坦克添加Box Collider
关于Box Collider详情可查看Unity Manual——Box Collider文档
- 添加刚体组件
4.控制坦克前后移动:
代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankMovement : MonoBehaviour
{
//定义速度
public float speed = 5;
//定义刚体
private Rigidbody rigidbody;
// Start is called before the first frame update
void Start()
{
//得到Rigidbody
rigidbody = this.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
//得到前后的按键,v是一个-1到1的值
float v = Input.GetAxis("Vertical");
//通过刚体组件给它施加一个速度
rigidbody.velocity = transform.forward * v * speed;
}
}
GetCompoment ()函数:
GetCompoment ()从当前游戏对象获取组件T,只在当前游戏对象中获取,没得到的就返回null,不会去子物体中去寻找。
详解:CSDN文档
Input.GetAxis()函数:
一、触屏类
1、Mouse X 鼠标沿屏幕X移动时触发
2、Mouse Y 鼠标沿屏幕Y移动时触发
3、Mouse ScrollWheel 鼠标滚轮滚动是触发
二、键盘类
1、Vertical 键盘按上或下键时触发
2、Horizontal 键盘按左或右键时触发
返回值是一个数,正负代表方向
官方文档:Input.GetAxis()函数
transform.forward函数:
transform.forward的值则等于当前物体的自身坐标系z轴在世界坐标上指向
详解:CSDN文档
同时由于坦克只在XZ轴运动,所以我们要把Y轴锁定;并且坦克只需要绕着Y轴旋转,所以把XZ轴锁定
- 控制坦克左右移动:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankMovement : MonoBehaviour
{
//定义速度
public float speed = 5;
//定义转速
public float angularSpeed = 30;
//定义刚体
private Rigidbody rigidbody;
// Start is called before the first frame update
void Start()
{
//得到Rigidbody
rigidbody = this.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
//得到前后的按键,v是一个-1到1的值
float v = Input.GetAxis("Vertical");
//通过刚体组件给它施加一个速度
rigidbody.velocity = transform.forward * v * speed;
//控制物体旋转
float h = Input.GetAxis("Horizontal");
rigidbody.angularVelocity = transform.up * h * angularSpeed;
}
}
坦克的参数也可以在这里更改
-
用WASD控制坦克1,用方向键控制坦克2
a)打开Prioect Settings
b)复制两遍Horizontal轴
c)Vertical也是如此d)代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankMovement : MonoBehaviour
{
//定义速度
public float speed = 20;
//定义转速
public float angularSpeed = 5;
//给每个坦克一个编号,通过编号区分不同的控制
public float number = 1;
//定义刚体
private Rigidbody rigidbody;
// Start is called before the first frame update
void Start()
{
//得到Rigidbody
rigidbody = this.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
//得到前后的按键,v是一个-1到1的值
float v = Input.GetAxis("VerticalPlayer"+number);
//通过刚体组件给它施加一个速度
rigidbody.velocity = transform.forward * v * speed;
//控制物体旋转
float h = Input.GetAxis("HorizontalPlayer"+number);
rigidbody.angularVelocity = transform.up * h * angularSpeed;
}
}
3、子弹
-
控制坦克子弹发射
在Model里面的Shell
先给子弹添加一个胶囊碰撞器
关于胶囊碰撞器的官方文档:胶囊碰撞器
再创建刚体Rigidbody
将其作为预制体后,创建一个空对象,用来确定子弹发射位置
并添加TankAttack脚本来控制子弹的发射
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankAttack : MonoBehaviour
{
public GameObject shellPrefab;
private Transform firePosition;
//发射键,默认为空格键
public KeyCode fireKey = KeyCode.Space;
// Start is called before the first frame update
void Start()
{
firePosition = transform.Find("FirePosition");
}
// Update is called once per frame
void Update()
{
//如果按键按下
if(Input.GetKeyDown(fireKey))
{
//实例化,发射方向和炮筒方向保持一致
GameObject.Instantiate(shellPrefab,firePosition.position,firePosition.rotation);
}
}
}
-
控制炸弹的飞行和爆炸
控制子弹的速度
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TankAttack : MonoBehaviour
{
public GameObject shellPrefab;
private Transform firePosition;
public float shellSpeed = 10;
//发射键,默认为空格键
public KeyCode fireKey = KeyCode.Space;
// Start is called before the first frame update
void Start()
{
firePosition = transform.Find("FirePosition");
}
// Update is called once per frame
void Update()
{
//如果按键按下
if(Input.GetKeyDown(fireKey))
{
//实例化,发射方向和炮筒方向保持一致
//每次实例化一个子弹时,得到子弹的刚体组件,再通过刚体组件给它速度
GameObject go = GameObject.Instantiate(shellPrefab,firePosition.position,firePosition.rotation)as GameObject;
//给刚体组件一个速度
go.GetComponent<Rigidbody>().velocity = go.transform.forward * shellSpeed;
}
}
}
在Shell中添加脚本控制其爆炸
并将刚体组件选为触发器
using UnityEngine;
using System.Collections;
public class Shell : MonoBehaviour {
public GameObject shellExplosionPrefab;
//触发检测
//只要进行触发,就爆炸,参数表示跟哪个碰撞器接触
public void OnTriggerEnter( Collider collider ) {
GameObject.Instantiate(shellExplosionPrefab, transform.position, transform.rotation);
GameObject.Destroy(this.gameObject);
}
}
同时给爆炸特效添加一个脚本,控制其自动销毁
using UnityEngine;
using System.Collections;
public class DestroyForTime : MonoBehaviour {
public float time;
// Use this for initialization
void Start () {
Destroy(this.gameObject,time);
}
// Update is called once per frame
void Update () {
}
}
3.控制炸弹对坦克的伤害
给坦克加一个Tank的标签,用以区分它是不是坦克。
这样子弹就可以检测它触碰到的是不是坦克,就可以给坦克伤害
using UnityEngine;
using System.Collections;
public class Shell : MonoBehaviour {
public GameObject shellExplosionPrefab;
public void OnTriggerEnter( Collider collider ) {
GameObject.Instantiate(shellExplosionPrefab, transform.position, transform.rotation);
GameObject.Destroy(this.gameObject);
//如果检测到的是坦克,给坦克发消息
if (collider.tag == "Tank") {
collider.SendMessage("TakeDamage");
}
}
}
坦克收到消息后减少血量
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class TankHealth : MonoBehaviour {
public int hp = 100;
public GameObject tankExplosion;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void TakeDamage() {
if (hp <= 0) return;
hp -= Random.Range(10, 20);
hpSlider.value = (float)hp /hpTotal;
if (hp <= 0) {//收到伤害之后 血量为0 控制死亡效果
GameObject.Instantiate(tankExplosion, transform.position + Vector3.up, transform.rotation);
GameObject.Destroy(this.gameObject);
}
}
}
4、控制相机视野的跟随
将视野设置在两个坦克的正中心
using UnityEngine;
using System.Collections;
public class FollowTarget : MonoBehaviour {
public Transform player1;
public Transform player2;
private Vector3 offset;
// Use this for initialization
void Start () {
//相机的位置减去中心的位置就得到了初始的偏移
offset = transform.position - (player1.position + player2.position)/2;
}
// Update is called once per frame
void Update () {
transform.position = (player1.position + player2.position)/2 + offset;
}
}
现在让视野跟着举距离进行变大变小
using UnityEngine;
using System.Collections;
public class FollowTarget : MonoBehaviour {
public Transform player1;
public Transform player2;
private Vector3 offset;
private Camera camera;
// Use this for initialization
void Start () {
offset = transform.position - (player1.position + player2.position)/2;
camera = this.GetComponent<Camera>();
}
// Update is called once per frame
void Update () {
//如果有一个被销毁了,就不做跟随了
if (player1 == null || player2 == null) return;
transform.position = (player1.position + player2.position)/2 + offset;
float distance = Vector3.Distance(player1.position, player2.position);
float size = distance*0.58f;
//正交距离
camera.orthographicSize = size;
}
}
5、添加音效
1.背景音效:
创建一个空对象,用它来播放背景音乐
2.坦克爆炸时的音效
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class TankHealth : MonoBehaviour {
public int hp = 100;
public GameObject tankExplosion;
public AudioClip tankExplosionAudio;
public Slider hpSlider;
private int hpTotal;
// Use this for initialization
void Start () {
hpTotal = hp;
}
// Update is called once per frame
void Update () {
}
void TakeDamage() {
if (hp <= 0) return;
hp -= Random.Range(10, 20);
hpSlider.value = (float)hp /hpTotal;
if (hp <= 0) {//收到伤害之后 血量为0 控制死亡效果
//表示播放某一个音效,在某一个点
AudioSource.PlayClipAtPoint(tankExplosionAudio,transform.position);
GameObject.Instantiate(tankExplosion, transform.position + Vector3.up, transform.rotation);
GameObject.Destroy(this.gameObject);
}
}
}
3、子弹发射的声音
using UnityEngine;
using System.Collections;
public class TankAttack : MonoBehaviour {
public GameObject shellPrefab;
public KeyCode fireKey = KeyCode.Space;
public float shellSpeed = 10;
public AudioClip shotAudio;
private Transform firePosition;
// Use this for initialization
void Start () {
firePosition = transform.Find("FirePosition");
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(fireKey)) {
AudioSource.PlayClipAtPoint(shotAudio,transform.position);
GameObject go = GameObject.Instantiate(shellPrefab, firePosition.position, firePosition.rotation) as GameObject;
go.GetComponent<Rigidbody>().velocity = go.transform.forward*shellSpeed;
}
}
}
4、子弹爆炸的声音
using UnityEngine;
using System.Collections;
public class Shell : MonoBehaviour {
public GameObject shellExplosionPrefab;
public AudioClip shellExplosionAudio;
public void OnTriggerEnter( Collider collider ) {
AudioSource.PlayClipAtPoint(shellExplosionAudio,transform.position);
GameObject.Instantiate(shellExplosionPrefab, transform.position, transform.rotation);
GameObject.Destroy(this.gameObject);
if (collider.tag == "Tank") {
collider.SendMessage("TakeDamage");
}
}
}
5、坦克行走时的音效
using UnityEngine;
using System.Collections;
using UnityEditor;
public class TankMovement : MonoBehaviour {
public float speed = 5;
public float angularSpeed = 30;
public float number = 1; //增加一个玩家的编号,通过编号区分不同的控制
//得到两个声音
public AudioClip idleAudio;
public AudioClip drivingAudio;
//得到声音源的组件
private AudioSource audio;
private Rigidbody rigidbody;
// Use this for initialization
void Start () {
rigidbody = this.GetComponent<Rigidbody>();
audio = this.GetComponent<AudioSource>();
}
void FixedUpdate() {
float v = Input.GetAxis("VerticalPlayer"+number);
rigidbody.velocity = transform.forward*v*speed;
float h = Input.GetAxis("HorizontalPlayer"+number);
rigidbody.angularVelocity = transform.up*h*angularSpeed;
//如果开始行走
if (Mathf.Abs(h) > 0.1 || Mathf.Abs(v) > 0.1) {
//修改默认的声音播放源
audio.clip = drivingAudio;
//如果当前没有播放
if(audio.isPlaying==false)
audio.Play();
}
else {
audio.clip = idleAudio;
if (audio.isPlaying == false)
audio.Play();
}
}
}
6、创建血条
先创建一个滑动器
先将Handle Slide Area先删除掉
将背景改为圆圈
将File也修改为圆圈
将Image Type 修改为Filed填充模式
最后将这个血条修改为3D模式
将画布的大小修改为40×40
将Slider的中心修改为0,0
最后在TankHealth中修改血条
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class TankHealth : MonoBehaviour {
public int hp = 100;
public GameObject tankExplosion;
public AudioClip tankExplosionAudio;
public Slider hpSlider;
//添加一个血条总量
private int hpTotal;
// Use this for initialization
void Start () {
hpTotal = hp;
}
// Update is called once per frame
void Update () {
}
void TakeDamage() {
if (hp <= 0) return;
hp -= Random.Range(10, 20);
//将比值赋值给value
hpSlider.value = (float)hp /hpTotal;
if (hp <= 0) {//收到伤害之后 血量为0 控制死亡效果
AudioSource.PlayClipAtPoint(tankExplosionAudio,transform.position);
GameObject.Instantiate(tankExplosion, transform.position + Vector3.up, transform.rotation);
GameObject.Destroy(this.gameObject);
}
}
}
最终效果
本文地址:https://blog.csdn.net/cui_hao_nan/article/details/107592235
上一篇: 明朝奇葩皇帝那么多 明朝为什么还能延续将近三百年时间
下一篇: 大富翁实现