Unity3D坦克大战游戏开发——学习笔记(上)

今天我们要学习的是小时候大家都玩过的坦克大战的游戏,采用的是Unity3D进行制作这款2D平面游戏。

1、新建项目

首先我们新建一个2D的新项目,这里不做介绍了。

2、资源导入

然后是资源的导入,地址:https://pan.baidu.com/s/1eGVzYU-pQLZntuGcFfm0Ww,密码:exqi。

下载好资源后将ReasourcePackage资源直接导入Assets即可。

3、搭建场景,处理资源

然后设置一下摄像头的一些参数,把游戏的窗口比例设置为5:4,利于最后的效果。

Unity3D坦克大战游戏开发——学习笔记(上)_第1张图片

 然后我们调整一下资源里面的图片属性,单张图片为Single,图集则为Mutiple,类型都为Sprite。

            Unity3D坦克大战游戏开发——学习笔记(上)_第2张图片Unity3D坦克大战游戏开发——学习笔记(上)_第3张图片

图集可任意通过SpriteEditor进行切割为一个个的小图片,模式有自动和按照一定大小切割。

4、预制体的制作,2D动画的制作

我们将资源中的坦克1拖入到场景中,设置大小为3,3,重命名为Player。

接着在资源中添加Prefabs文件夹用于存放预制体,将上面的Player玩家拖入。

然后将Map资源里面的图片都拖入进来,设置合适的大小,或者直接复制Player,将其Sprite的属性改为相应的图片即可。改成相应的名字后都拖入到Prefabs中待使用。

Unity3D坦克大战游戏开发——学习笔记(上)_第4张图片                   Unity3D坦克大战游戏开发——学习笔记(上)_第5张图片

接着新建Animation和Animatoe Controller两个文件夹分别存放动作和动作控制器。

创建动画有很多种方式,这里简单介绍一种,我们以出生动画为例,选中出生的资源图片图集,选中图集中的四个图片,点击第一张图片按住shift不松,然后选中最后一张,往场景里面拖就可以创建动画了。设置一下动画的大小为3,3。将创建出来的东西拖放到对应文件夹下:

 然后将出生的特效拖放到预制体中,这里我们对预制体进行一个分类,分为Map的预制体和Effect的预制体。把出生拖入到Effect中。同理我们做出爆炸动画、护盾动画以及河流的动画。最后效果如图所示:

Unity3D坦克大战游戏开发——学习笔记(上)_第6张图片

5、控制玩家的移动

控制玩家的移动需要用到代码了,所以我们新建一个Scripts文件夹用来存放所有的代码,然后新建脚本PlayerAI用来控制玩家的移动,然后将该脚本挂载到玩家上,进行编辑:

    public float moveSpeed = 3;//坦克的移动速度    

    void Update()
    {
        float h = Input.GetAxisRaw("Horizontal");//获得玩家的水平轴输入
        float v = Input.GetAxisRaw("Vertical");//获得玩家的垂直轴输入

        //开始移动
        transform.Translate(Vector3.right * h * moveSpeed * Time.deltaTime, Space.World);//水平移动
        transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);//垂直移动
    }

然后就是移动的效果:

       Unity3D坦克大战游戏开发——学习笔记(上)_第7张图片

6、控制图片的移动切换

上一小节玩家可以移动了,但是移动的时候坦克的朝向一直没有变化,这显然是不合理的,所以我们需要设置坦克移动的时候朝向也会跟着方向一起变化。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAI : MonoBehaviour
{
    public float moveSpeed = 3;//坦克的移动速度
    private SpriteRenderer spriteRender;//坦克的渲染组件
    public Sprite[] tankSprite;//坦克的精灵 上右下左

    private void Awake()
    {
        spriteRender = GetComponent();//获取坦克的渲染组件
    }

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        float h = Input.GetAxisRaw("Horizontal");//获得玩家的水平轴输入
        float v = Input.GetAxisRaw("Vertical");//获得玩家的垂直轴输入

        //开始移动
        transform.Translate(Vector3.right * h * moveSpeed * Time.deltaTime, Space.World);//水平移动
        transform.Translate(Vector3.up * v * moveSpeed * Time.deltaTime, Space.World);//垂直移动

        //调整坦克的朝向图片
        if (h < 0)
            spriteRender.sprite = tankSprite[3];
        else if (h > 0)
            spriteRender.sprite = tankSprite[1];

        if (v < 0)
            spriteRender.sprite = tankSprite[2];
        else if (v > 0)
            spriteRender.sprite = tankSprite[0];

    }
}

我们还需要拖入相对应的图片对公有变量tankSprite进行赋值

Unity3D坦克大战游戏开发——学习笔记(上)_第8张图片

然后是效果:

             

7、添加碰撞器,解决抖动问题

碰撞器是设计游戏中经常用到得组件,只要需要判断物体之间是否发生了碰撞都要用到这个组件。我们给每个物体都添加一个碰撞器,在移动的物体上还要添加刚体,需要注意的是因为这是个2D游戏,所以添加的都是2D的组件。

              Unity3D坦克大战游戏开发——学习笔记(上)_第9张图片            Unity3D坦克大战游戏开发——学习笔记(上)_第10张图片

我们给玩家和地图的预制体都添加上BoxCollider2D的组件,然后给玩家额外添加一个Rigidbody2D,这样就可以进行碰撞了,需要注意的是设置重力Gravity Scale为0,勾选上Freeze Rotation锁定Z轴方向的旋转。

但是碰撞时会一直抖动,为了解决这个问题我们需要代码操作,我们将Update中的所有代码移到FixedUpdate中就可以了

    private void FixedUpdate()//生命周期函数,在Update之后执行,固定了每一帧的时间
    {
        float h = Input.GetAxisRaw("Horizontal");//获得玩家的水平轴输入
        float v = Input.GetAxisRaw("Vertical");//获得玩家的垂直轴输入

        //开始移动
        transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);//水平移动
        transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);//垂直移动

        //调整坦克的朝向图片
        if (h < 0)
            spriteRender.sprite = tankSprite[3];
        else if (h > 0)
            spriteRender.sprite = tankSprite[1];

        if (v < 0)
            spriteRender.sprite = tankSprite[2];
        else if (v > 0)
            spriteRender.sprite = tankSprite[0];
    }

8、添加移动优先级,2D渲染层级问题

还有一个问题是,当我们按多个方向键时,坦克会斜着走,这显然是不合理的,为了解决这个问题,我们添加了移动的优先级,让他只能往上下左右一个方向走。我们修改一下代码就可以了,把移动封装到一个函数里面放到FixedUpdate调用:

    private void FixedUpdate()//生命周期函数,在Update之后执行,固定了每一帧的时间
    {
        TankMove();
    }

    private void TankMove()//坦克移动控制函数
    {
        float h = Input.GetAxisRaw("Horizontal");//获得玩家的水平轴输入
        float v = Input.GetAxisRaw("Vertical");//获得玩家的垂直轴输入

        //开始移动
        transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);//水平移动

        //调整坦克的朝向图片
        if (h < 0)
            spriteRender.sprite = tankSprite[3];
        else if (h > 0)
            spriteRender.sprite = tankSprite[1];

        if (h != 0)//如果已经按下了水平方向,则不允许有垂直操作,直接返回
            return;

        transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);//垂直移动

        //调整坦克的朝向图片
        if (v < 0)
            spriteRender.sprite = tankSprite[2];
        else if (v > 0)
            spriteRender.sprite = tankSprite[0];
    }

 还有一个需要实现的是渲染的优先级,简单来说就是坦克在通过草丛时我们需要草丛显示在上方,子弹通过和河流时我们希望子弹在上方,类似于这种。渲染的优先级我们是通过Sprite Renderer组件里面的Order in Layer这个值来设置的,值大的物体会覆盖显示在值小的物体上。

Unity3D坦克大战游戏开发——学习笔记(上)_第11张图片

9、坦克的攻击方法

攻击主要涉及的是子弹的实例化,我们添加一个攻击函数,然后在FixedUpdate中调用。

    private void TankAttack()//坦克攻击函数
    {
        if(Input.GetKeyDown(KeyCode.Space))//如果玩家按下了空格键
        {
            Instantiate(bulletPrefab, transform.position, transform.rotation);//子弹进行实例化
        }
    }

下面是效果,可以看到子弹出来了,但是子弹的方向只有一个方向的:

Unity3D坦克大战游戏开发——学习笔记(上)_第12张图片

10、子弹的朝向

我们可以通过添加不同的子弹方向图片来改变朝向,像之前坦克的朝向改变一样,还可以直接改变子弹的方向,下面我们直接用这种方法试试。

我们定义一个子弹需要旋转的角度bulletEulerangles,在坦克移动时进行赋值。

    private Vector3 bulletEulerangles;//子弹应该旋转的欧拉角

    private void TankMove()//坦克移动控制函数
    {
        float h = Input.GetAxisRaw("Horizontal");//获得玩家的水平轴输入
        float v = Input.GetAxisRaw("Vertical");//获得玩家的垂直轴输入

        //开始移动
        transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);//垂直移动

        //调整坦克的朝向图片
        if (v < 0)
        {
            spriteRender.sprite = tankSprite[2];
            bulletEulerangles = new Vector3(0, 0, 180);
        }
        else if (v > 0)
        {
            spriteRender.sprite = tankSprite[0];
            bulletEulerangles = new Vector3(0, 0, 0);
        }

        if (v != 0)//如果已经按下了水平方向,则不允许有垂直操作,直接返回
            return;

        //开始移动
        transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);//水平移动

        //调整坦克的朝向图片
        if (h < 0)
        {
            spriteRender.sprite = tankSprite[3];
            bulletEulerangles = new Vector3(0, 0, 90);
        }
        else if (h > 0)
        {
            spriteRender.sprite = tankSprite[1];
            bulletEulerangles = new Vector3(0, 0, -90);
        }
    }

下面是效果,可以看到子弹的方向正确了:

Unity3D坦克大战游戏开发——学习笔记(上)_第13张图片

你可能感兴趣的:(Unity3D,unity,游戏开发)