用户登录
用户注册

分享至

unity3d实战c#语言编写坦克大战游戏

  • 作者: 沙漠之鱼8185584
  • 来源: 51数据库
  • 2021-07-30

unity3d 坦克大战实战

来源:siki学院-unity3d 坦克大战实战
资源包:https://pan.baidu.com/s/17Ei5tZcDaKO1VlG4AzDc-A
密码:ytnc

1、场景设置


图片展示

在开始时,设置Lighting Settings中的Scene场景的自动渲染功能取消,这样会节省时间,一般发布时再渲染。


同时渲染场景,将图中颜色映射到整个场景中

渲染后的效果如图所示:

再Main camera中选择正交视野

2、控制坦克的前后左右移动

  1. 给坦克添加冒烟的特效:


在Prefabs中有DustTrail就是冒烟特效,将特效用Ctrl+D复制一份,分别拖到履带下

  1. 给坦克添加Box Collider


关于Box Collider详情可查看Unity Manual——Box Collider文档

  1. 添加刚体组件


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轴锁定

  1. 控制坦克左右移动:
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;
    }
   


	
} 

坦克的参数也可以在这里更改

  1. 用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、子弹

  1. 控制坦克子弹发射
    在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);
        }
        
    }
} 

  1. 控制炸弹的飞行和爆炸
    控制子弹的速度
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);
        }
    }
} 


最终效果

本文地址:http://www.51sjk.com/Upload/Articles/1/0/262/262803_20210702003247420.jpg

软件
前端设计
程序设计
Java相关