Unity入门开发实战——俯视角3D射击游戏项目实战

第二章_2.6_3D射击游戏实现

前言
由于工作用的电脑配置太低了,在优快云中编写的笔记字数一多就会卡,所以这段时间的笔记就一直没有上传。
这个项目是我在学习的Unity开发中认为一个比较好且非常适合新手做的项目,所以在这里分享给大家。
本项目参考自《Unity3D 脚本编程和游戏开发》中的第二章,强烈建议大家阅读,是本很适合新手入门的书。
在这里插入图片描述

本项目的资源文件:资源下载

2.6.0 效果

实现效果

2.6.1 实现功能

  • 玩家移动
  • 摄像机跟随
  • 武器系统和子弹
  • 敌人角色
  • 子弹击中逻辑
  • 人物死亡效果

2.6.2 创建主角以及玩家移动

创建主角主要由一个胶囊体作为主体,一个方体作为面部,其效果如下:

在这里插入图片描述

另外,我们将一个平面作为地板,其大小放大四倍。

主角移动逻辑代码

代码逻辑:

  1. 获取玩家输入,将输入封装为一个向量
  2. 在玩家角色并未死亡的前提下,根据玩家输入向量设置玩家的移动速度
  3. 根据玩家的输入向量设置玩家朝向
  4. 限制玩家的移动范围,超出范围将玩家修改为范围内
    
     void Update()
    {
   
   
        inputVector = GetInputVector();
        if (!isDead)
        {
   
   
            Move();
        }
    }

    /// <summary>
    /// 获取玩家输入向量
    /// </summary>
    /// <returns>玩家输入向量</returns>
    private Vector3 GetInputVector()
    {
   
   
        float horizontalInput = Input.GetAxisRaw("Horizontal");
        float verticalInput = Input.GetAxisRaw("Vertical");
        return new Vector3(horizontalInput, 0, verticalInput);
    }

     /// <summary>
    /// 玩家移动方法
    /// </summary>
    private void Move()
    {
   
   
        //设置移动速度
        AdjustVelocity();
        //设置玩家朝向
        AdjustForward();
        //设置边界
        BorderLimit();

        /// <summary>
        /// 设置玩家速度
        /// </summary>
        void AdjustVelocity()
        {
   
   
            //将输入向量归一化,向量的模长为1,保证每个方向的速度相同
            inputVector = inputVector.normalized;
            rb.velocity = inputVector * speed;
        }

        /// <summary>
        /// 设置玩家朝向
        /// </summary>
        void AdjustForward()
        {
   
   
            //如果输入的值不是很小的话,将物体转向前进方向
            if (inputVector.magnitude > 0.1f)
            {
   
   
                transform.forward = inputVector;
            }
        }

        /// <summary>
        /// 限制玩家移动范围
        /// </summary>
        void BorderLimit()
        {
   
   
            //限制玩家的移动范围
            Vector3 temp = transform.position;
            //Math.Clamp(value,min,max) : 在最大最小范围中间取值,如果超过范围,则返回最大/最小值
            temp.x = Mathf.Clamp(temp.x, -BORDER, BORDER);
            temp.z = Mathf.Clamp(temp.z, -BORDER, BORDER);
            transform.position = temp;
        }
    }

知识点

①:向量归一化

向量归一化,即将向量的长度改为1。

假设vector为一个向量,可以使用vector.normalized来获取这个向量的归一化向量,或者使用vector.Normalize()来将这个向量归一化。

②:Mathf.Clamp(value,min,max)

使value在min和max中间取值,如果value大于最大值在返回max,如果小于最小值那么返回min

③:内部方法

在方法内部的方法,C#的特性,允许我们在一个方法的内部再编写方法。

但是编写的方法仅仅可以在方法内部被调用。

目前貌似不推荐使用这个方法,因为这样限制了方法的复用度,以后不用了。

④:transform.forward

物体面朝方向,长度为1,初始情况下是面向Z轴方向,此时transform.forward为(0,0,1)。之后随着物体旋转而改变。

2.6.3 摄像机跟随

我们创建一个2D Camera,并且将其跟随的目标设置为Player物体即可。

请添加图片描述

注意:我们必须创建2D Camera,如果创建的物体是Virtual Camera的话,摄像机会随着玩家转向也一起转向。

2.6.4 实现武器系统

书中的武器系统较为简陋,没有创建武器对应的类,不利于以后添加新的武器。所以在此我做出了一点小调整:

  • 创建Gun类,其中包括武器的相关信息(包括开火位置、射速、子弹数等)

  • 在人物物体(GameObject)之下创建一个名为WeaponBag的物体,其中子物体是武器物体。

    • 武器物体包括几个简单物体拼接而成的武器模型
    • 武器物体挂载Gun脚本的组件,以此设置武器的属性
    • 武器物品必须要有一个名为FirePosition的空物体,此物体表示该武器的开火位置,也就是“子弹从哪里打出来”
  • WeaponBag物体上挂载了一个对应的脚本,其脚本的作用是获取WeaponBag的所有子物体中的所有子物体的Gun组件

  • 所有武器的操作由WeaponController操控,WeaponController目前实现了武器开火以及武器切换这两个重要功能

  • 当然最后还有创建子弹相关的脚本以及物体

Gun类代码

代码:

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

/// <summary>
/// 枪械类
/// </summary>
public class Gun : MonoBehaviour
{
   
   
    /// <summary>
    /// 射出的子弹
    /// </summary>
    public GameObject bulletPerfab;
    /// <summary>
    /// 射击间隔
    /// </summary>
    public float fireCD;
    /// <summary>
    /// 是否持续射击
    /// </summary>
    public bool isHoldToFire;
    /// <summary>
    /// 一次射击的子弹个数
    /// </summary>
    public int onceFireBulletNumber;
    /// <summary>
    /// 子弹射出间隔角度(当子弹个数为复数时使用)
    /// </summary>
    public float bulletAngle;
    /// <summary>
    /// 每个子弹伤害
    /// </summary>
    public float damage;
    /// <summary>
    /// 子弹飞行速度
    /// </summary>
    public float bulletVelocity;
    /// <summary>
    /// 子弹持续时间
    /// </summary>
    public float bulletLifeTime;
    /// <summary>
    /// 子弹射出位置
    /// </summary>
    public Transform fireTransform;
}

一个简单的Gun物体示例:

请添加图片描述

WeaponBag功能实现

实现原理如图:

在这里插入图片描述

为了代码的灵活性,我们并不需要手动设定规定一个人物物品持有几个武器。所以就需要在WeaponBag的组件中使用GetComponentsInChildren()方法,获取子物体中的所有Gun组件,并且将他们存放在一个数组中。

实现代码如下:

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

public class WeaponBag : MonoBehaviour
{
   
   
    public List<Gun> guns;
    // Start is called before the first frame update
    void Awake()
    {
   
   
        //获取所有子物体的Gun组件
        Gun[] gunsInBag = GetComponentsInChildren<Gun>();
        guns = new List<Gun>(gunsInBag);
    }
}

如此一来,我们的WeaponController只需要获取WeaponBag组件,就可以“知道”这个人物有多少种枪械了。

WeaponController实现

WeaponController主要实现了武器开火和武器切换功能。

  • 武器切换

武器切换的逻辑:设置一个int类型的变量curGun,当切换武器时curGunweaponBagguns列表中增加,如果超出列表下标则回到最初的0下标;当武器切换时,先将当前武器(旧武器)设置为未激活状态,再等curGun增加后,将目前武器(新武器)设置为激活状态。

另外:在WeaponContoller启动时会将除了curGun之外的所有武器都设置为未激活状态。

实现代码:

    /// <summary>
    /// 切换武器
    /// </summary>
    /// <returns>当前武器序号</returns>
    /// <remarks>
    /// 将当前武器设置为未激活,然后将列表中的下一个武器激活
    /// </remarks>
    public int ChangeWeapon()
    {
   
   
        DeactiveCurrentWeapon()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值