首页 > 其他分享 >Unity3D学习FPS游戏(6)武器发射子弹

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

时间:2024-10-28 08:51:20浏览次数:8  
标签:Unity3D isFire 子弹 transform currentBulletNum 发射 FPS public

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

子弹

子弹发射位置

在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;// 等待一帧
        }
    }
}

效果

在这里插入图片描述

标签:Unity3D,isFire,子弹,transform,currentBulletNum,发射,FPS,public
From: https://blog.csdn.net/qq_40306845/article/details/143279309

相关文章

  • 【原创】修正fpspreadsheet读某些复杂xlsx文件时出错的Bug
    网友“海”在使用fpspreadsheet时遇到读取复杂的xlsx文件会出错: 经跟踪发现运行到fpspreadsheet\source\common\xlsxooxml.pas的procedureTsSpreadOOXMLReader.ReadFromStream的ReadDefinedNames(Doc.DocumentElement.FindNode('definedNames'))这行出错,查看早期(fpspreadsheet......
  • FPS-Frontiers in Plant Science
    @目录一、征稿简介二、重要信息三、服务简述四、投稿须知一、征稿简介二、重要信息期刊官网:https://ais.cn/u/3eEJNv三、服务简述FrontiersinPlantScience是在植物研究领域领先的期刊,通过出版严格的同行评审来推动我们对于植物生物学这一领域认知的进步,这本多学科开放......
  • Unity3D教程:次表面散射的简单实现
    次表面散射指的是光线射入半透明材质,在内部发生散射后再透射出来的光线传播过程,考虑到有些项目会需要使用次表面散射,下面就给大家介绍下在Unity3D中次表面散射的简单实现,希望可以帮到大家。 一、前言本文旨在与大家一起探讨学习新知识,如有疏漏或者谬误,请大家不吝指出。以下内......
  • Unity3D c# 使对象物体始终面向摄像机
    usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassLookAtMainCamera:MonoBehaviour{ //Usethisforinitialization voidStart(){ } //Updateiscalledonceperframe voidUpdate(){......
  • YOLOv11性能评估指标 AP、mAP、Precision、Recall、FPS、IoU、混淆矩阵、F1等YOLO相关
    开始讲解之前推荐一下我的专栏,本专栏的内容支持(分类、检测、分割、追踪、关键点检测),专栏目前为限时折扣,欢迎大家订阅本专栏,本专栏每周更新3-5篇最新机制,更有包含我所有改进的文件和交流群提供给大家。 专栏回顾:YOLOv11改进系列专栏——本专栏持续复习各种顶会内容——科......
  • 卡关?不存在的!《死亡细胞》风灵月影十三项修改器:无限生命/无视伤害判定/无限箭/子弹
    死亡细胞修改器,专为《DeadCells》游戏定制,是一款功能多样、操作简便、实用性强的游戏辅助工具。它提供13项强大修改功能,助力玩家轻松享受游戏乐趣,优化游戏体验。修改器地址:https://bbs.18183.com/thread-6959-1-1.htmlhttps://bbs.18183.com/thread-6959-1-1.html修改器功......
  • 项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持
    若该文为原创文章,转载请注明出处本文章博客地址:https://hpzwl.blog.csdn.net/article/details/142454993长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…Qt开发专栏:项目实战......
  • 项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持
    需求  1.使用osg三维引擎进行动力学模型仿真性能测试;  2.打开动力学仿真模型文件,.k后缀的模型文件,测试加载解析过程;  3.解决第三方company的opengl制作的三维引擎,绘制面较多与弹丸路径模拟较卡顿的问题;  4.测试时,使用的模型为公开模型,基础面数量达到160多万个;  5.测......
  • Android平台Unity3D下如何同时播放多路RTMP|RTSP流?
    技术背景好多开发者,提到希望在Unity的Android头显终端,播放2路以上RTMP或RTSP流,在设备性能一般的情况下,对Unity下的RTMP|RTSP播放器提出了更高的要求。实际上,我们在前几年发布Unity下直播播放模块的时候,就已经支持了Android多实例播放RTMP|RTSP,随着大家对这块的技术诉求和性能要求越......
  • 音视频生态下Unity3D和虚幻引擎(Unreal Engine)的区别
    技术背景好多开发者跟我们做技术交流的时候,会问我们,为什么有Unity3D的RTMP|RTSP播放模块,还有RTMP推送和轻量级RTSP服务模块,为什么不去支持虚幻引擎?二者区别在哪里?本文就Unity3D和虚幻引擎之间的差异,做个大概的分析,实际上,Unity3D和虚幻引擎(UnrealEngine)在游戏开发及其他相关领域都......