Unity3D学习FPS游戏(6)武器发射子弹

前言:上一篇中设置好了武器的瞄准,本篇将实现一个武器发射子弹的效果。

子弹

子弹发射位置

在Weapon01下面新建一个GameObject用来设置发射子弹的位置,调整Position放在枪口位置。
在这里插入图片描述

子弹模型

子弹模型

在下面路径找到子弹模型,然后拖入到项目中,并右键Prefab-unpack(为了避免影响到原本素材中的预制体)。
在这里插入图片描述
子弹材质

然后子弹模型本身是没有材质的,和我们之前拖入枪模型的时候一样,找到下面路径的材质,给它附上。
在这里插入图片描述

子弹完整代码

思路

思路非常简单,子弹生成后,应该朝着前方移动一定距离,后销毁。

代码

新建C#代码,BulletController,挂载在Bullet01上。

设置两个参数,移动速度和移动距离。

子弹的移动和物理相关,所以使用FixedUpdate进行更新。

public class BulletController : MonoBehaviour
{
    [Header("子弹数值")]
    public float bulletSpeed=1000;// 移动速度
    public float range = 10000;// 移动距离

    private void FixedUpdate()
    {
        transform.position+=transform.forward *bulletSpeed * Time.fixedDeltaTime;// 每次移动位移
        range -= bulletSpeed * Time.fixedDeltaTime;// 每次移动范围减少
        if (range <= 0)
        {
            Destroy(this.gameObject);// 抵达范围终点,销毁
        }
    }
}

子弹预制体

把子弹命名为Bullet01,然后拖拽到文件夹中生成预制体。

默认子弹模型的大小还挺小的,记得缩放Scale到自己能看到的大小,我设置了0.5倍。
在这里插入图片描述

发射子弹代码

思路

参数

我们需要实现发射子弹,并且按下左键连续发射子弹,而且还有弹夹数量。

会需要如下的参数,发射子弹得有发射位置和子弹的预制体;连续发射子弹得判断发射状态和子弹的间隔时间;弹夹数量得有弹夹总数和当前子弹数。

[Header("子弹数值")]
public Transform shootPoint;// 子弹发射位置
public GameObject bullet;// 子弹预制体
public float shootInterval = 1;// 子弹间隔时间
private bool isFire;// 发射状态
public int bulletNum = 100;// 弹夹
public int currentBulletNum;// 当前子弹的数量

功能

按下左键后,开启发射子弹;松开左键后,停止发射子弹。

private void OpenFire()
{
    if (Input.GetMouseButtonDown(0))
    {
        isFire = true;
        StartCoroutine("Shoot");
    }
    if (Input.GetMouseButtonUp(0))
    {
        isFire = false;
        StopCoroutine("Shoot");
    }
}

发射子弹就是创建子弹,每个子弹生产间隔一段时间。
弹夹,产生一个子弹将数量减少,子弹数量为了0的时候将不生产。
可以用和上一篇武器瞄准的协程方法,只不过间隔不是帧数而是时间。

IEnumerator Shoot()
{
    while (isFire)
    {
        if (currentBulletNum >0)
        {
            GameObject newBullet = Instantiate(bullet, shootPoint);
            currentBulletNum--;
        }
        yield return new WaitForSeconds(shootInterval);// 间隔一定时间再发射下一个子弹
    }
}

完整代码

WeaponController更新后的完整代码:

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

public class WeaponController : MonoBehaviour
{
    [Header("武器数值")]
    public Vector3 defaultPosition;// 默认位置
    public Vector3 centerPosition;// 中心位置
    public float positionLerpRatio = 0.5f;// 线性插值参数

    [Header("子弹数值")]
    public Transform shootPoint;// 子弹发射位置
    public GameObject bullet;// 子弹预制体
    public float shootInterval = 1;// 子弹间隔时间
    private bool isFire;// 发射状态
    public int bulletNum = 100;// 弹夹
    public int currentBulletNum;// 当前子弹的数量

    void Start()
    {
        // 自己在Unity中挪位置试出来的
        defaultPosition = new Vector3(0.4F, -0.6F, 1.15F);
        centerPosition = new Vector3(0F, -0.6F, 0.807F);
        currentBulletNum = bulletNum;
    }

    void Update()
    {
        ChangePosition();
        OpenFire();
    }

    private void OpenFire()
    {
        if (Input.GetMouseButtonDown(0))
        {
            isFire = true;
            StartCoroutine("Shoot");
        }
        if (Input.GetMouseButtonUp(0))
        {
            isFire = false;
            StopCoroutine("Shoot");
        }
    }
    IEnumerator Shoot()
    {
        while (isFire)
        {
            if (currentBulletNum >0)
            {
                GameObject newBullet = Instantiate(bullet, shootPoint);
                currentBulletNum--;
            }
            yield return new WaitForSeconds(shootInterval);
        }
    }
    private void ChangePosition()
    {
        // 按下左键
        if (Input.GetMouseButtonDown(1))
        {
            StopCoroutine("ToDefault");
            StartCoroutine("ToCenter");
        }
        // 松开左键
        if (Input.GetMouseButtonUp(1))
        {
            StopCoroutine("ToCenter");
            StartCoroutine("ToDefault");
        }
    }
    IEnumerator ToCenter() {
        while (transform.localPosition!=centerPosition)
        {
            transform.localPosition = Vector3.Lerp(transform.localPosition, centerPosition, positionLerpRatio);
            yield return null;// 等待一帧
        }
    }
    IEnumerator ToDefault()
    {
        while (transform.localPosition != defaultPosition)
        {
            transform.localPosition = Vector3.Lerp(transform.localPosition, defaultPosition, positionLerpRatio);
            yield return null;// 等待一帧
        }
    }
}

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值