Unity3D学习FPS游戏(10)子弹攻击敌人掉血(碰撞检测)

news2024/11/6 10:21:27

前言:前面最然创造出带有血条的敌人,但子弹打中敌人并没有效果。所以本篇将实现子弹攻击敌人,并让敌人掉血。

子弹攻击敌人掉血

  • 整体思路
    • 目标
    • 补充知识-碰撞检测
  • 准备工作
    • 刚体和碰撞器添加
    • 添加刚体后子弹代码优化
    • 补充知识-标签系统
    • Tag添加
  • 碰撞检测代码编写
    • 敌人受伤
    • 子弹OnCollisionEnter函数
  • 效果

整体思路

目标

子弹碰到敌人后,进行一个碰撞检测。
判断碰敌人到后,子弹会被对象池回收,然后敌人会掉血,敌人血量掉到最低会自动销毁。
判断碰底板到后,子弹会被对象池回收。

补充知识-碰撞检测

Unity中默认生成的GameObject是没有物理也没有碰撞的,transform坐标移到哪里就是哪里。

Unity碰撞检测要求:

  • 两个物体都有碰撞器(Collider)
  • 运动的物体有刚体(Rigidbody)

关于刚体(Rigidbody)和碰撞器(Collider)组件的介绍:

  • 刚体(Rigidbody):使游戏对象在物理系统的控制下来运动,具有力的作用。
  • 碰撞器(Collider):碰撞器是物理组件的一类,它要与刚体一起添加到游戏对象上才能触发碰撞,碰撞器的大小形状规定物体发生碰撞的范围。

为什么碰撞检测不能只有碰撞器没有刚体?
因为判断碰撞就是需要计算力,刚体才能受到力的作用。

碰撞检测方法通常分为两种Collision碰撞和Trigger触发:

  • Collision碰撞
    函数:OnCollisionEnter/OnCollisionStay/OnCollisionExit
    效果:有一个相互作用的力,造成回弹的效果。
    条件:双方都有Collider,至少有一个运动的物体有Rigidbody。如果有Collider勾选了isTrigger或者刚体勾选了Kinematic,则碰撞无效。
  • Trigger触发
    函数:OnTriggerEnter/OnTriggerStay/OnTriggerExit
    效果:不会发生物体碰撞,也不会受到重力等物理作用力的影响,双方会直接穿过。
    条件:双方都有Collider,至少有一个运动的物体有Rigidbody。至少有一个碰撞体勾选IsTrigger。

Collision碰撞和Trigger触发的碰撞检测函数含义:

  • Enter事件表示两个物体接触瞬间,会执行一次事件。
  • Stay事件表示两个物体一直接触,会持续执行这个事件。
  • Exit事件表示两个物体分开瞬间,会执行一次事件。

isTrigger就是碰撞器中的一个属性,勾选之后可以就是触发器,不会发生碰撞,可以用做一些金币检测。
Kinematic是刚体的一个属性,在碰撞期间的行为类似于不可移动的对象,不受力的作用,但是可以进行速度操控。

准备工作

刚体和碰撞器添加

这里使用Collision碰撞,在FPS游戏中,常常会有打中怪的时候,怪往后退的效果,例如以前玩的“穿越火线”。

给子弹还有敌人添加胶囊形状碰撞体(Capsule Collider),不同碰撞体其实就是形状上的不太一样。
在这里插入图片描述
给子弹添加刚体。
在这里插入图片描述
添加新的组件后,子弹预制体如何更新。
在这里插入图片描述
敌人也加上胶囊碰撞体,因为碰撞检测需要碰撞双方都有碰撞体。
在这里插入图片描述

添加刚体后子弹代码优化

之前我们是通过计算transform位移更新子弹位置的,现在我们可以直接调用刚体的速度进行更新子弹位置。射程可以用时间来判断,速度恒定,调整移动时间其实也就规定了射程。

public class BulletController : MonoBehaviour
{
    private Rigidbody bulletRigidbody;// 刚体

    [Header("子弹数值")]
    public float bulletSpeed=100;// 子弹射速
    public float lifeTime = 10;// 子弹生存时间

    public ObjectPool<GameObject> bulletPool;

    private void Start()
    {
        bulletRigidbody = GetComponent<Rigidbody>();
    }

    private void FixedUpdate()
    {
        bulletRigidbody.velocity=transform.forward * bulletSpeed;
        lifeTime -= Time.fixedDeltaTime;
        if (lifeTime <= 0)
        {
            //Destroy(this.gameObject);
            bulletPool.Release(this.gameObject);
        }
    }

    public void BulletReset()
    {
        transform.localPosition = new Vector3(0,0,0);
        lifeTime = 10;
    }
}

补充知识-标签系统

标签 (Tag) 是可分配给一个或多个游戏对象的参考词。

标签有助于识别游戏对象以便于编写脚本。例如,可为玩家控制的角色定义“Player”标签,并为非玩家控制的角色定义“Enemy”标签。

标签对碰撞体控制脚本中的触发器很有用;例如,需要通过标签确定玩家是否与敌人、道具或可收集物进行交互。

Tag添加

给建筑物体添加Plane标签;玩家添加Player标签;敌人添加Enemy标签。

标签添加方式如下:
在这里插入图片描述
在这里插入图片描述

碰撞检测代码编写

有了前面的准备,现在要做的事情就很简单了,主要是把OnCollisionEnter函数部分编写好,以及敌人受伤。

敌人受伤

创建一个新的代码命名为EnemyController。

敌人血条的逻辑联动和之前武器的弹夹数量是一样的,初始化的时候设置好Slider大小和当前大小,每次血量减少的时候就更新血条。
设置好敌人的血量,编写一个Damage函数,让子弹碰撞的时候调用,进行血量的更新操作。

public class EnemyController : MonoBehaviour
{
    [Header("血量数值")]
    public Slider HPSlider;// 血量Slider UI
    public float HP = 100;// 血量
    void Start()
    {
        if (HPSlider)
        {
            HPSlider.maxValue = HP;
            HPSlider.value = HP;
        }
    }
    public void Damage(float damage)
    {
        if (HP > 0)// 有血量
        {
            HP -= damage;
            if(HPSlider)// 更新血条
                HPSlider.value = HP;
        }
        if (HP <= 0)// 敌人无血量则销毁
            Destroy(this.gameObject);
    }
}

子弹OnCollisionEnter函数

子弹主要是添加OnCollisionEnter函数,碰撞检测时候,如果碰到是敌人,调用敌人的Damge函数,再销毁子弹。

public float attackNum = 20;// 子弹攻击力
private void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Enemy"))// 通过Tag判断是不是敌人
    {
        collision.gameObject.GetComponent<EnemyController>().Damage(attackNum);// 调用敌人攻击代码
    }
    Destroy(this.gameObject);// 碰到别的碰撞体就销毁
}

效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2234208.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AMD显卡低负载看视频掉驱动(chrome edge浏览器) 高负载玩游戏却稳定 解决方法——关闭MPO

问题 折磨的开始是天下苦黄狗久矣&#xff0c;为了不再被讨乞丐的显存恶心&#xff0c;一怒之下购入了AMD显卡&#xff08;20GB显存确实爽 头一天就跑了3dmark验机&#xff0c;完美通过&#xff0c;玩游戏也没毛病 但是呢这厮是一点不省心&#xff0c;玩游戏没问题&#xff0c…

服装品牌零售业态融合中的创新发展:以开源 AI 智能名片 S2B2C 商城小程序为视角

摘要&#xff1a;本文以服装品牌零售业态融合为背景&#xff0c;探讨信息流优化和资金流创新的重要作用&#xff0c;并结合开源 AI 智能名片 S2B2C 商城小程序&#xff0c;分析其如何进一步推动服装品牌在零售领域的发展&#xff0c;提高运营效率和用户体验&#xff0c;实现商业…

【数据库】elasticsearch

1、架构 es会为每个索引创建一定数量的主分片和副本分片。 分片&#xff08;Shard&#xff09;&#xff1a; 将索引数据分割成多个部分&#xff0c;每个部分都是一个独立的索引。 主要目的是实现数据的分布式存储和并行处理&#xff0c;从而提高系统的扩展性和性能。 在创建索…

语言模型的评测

语言模型的评测 内在评测 在内在评测中&#xff0c;测试文本通常由与预训练中所用的文本独立同分布的文本构成&#xff0c;不依赖于具体任务。最为常用的内部评测指标是困惑度&#xff08;Perplexity&#xff09; 困惑度是衡量语言模型对测试文本预测能力的一个指标&#xf…

Golang | Leetcode Golang题解之第535题TinyURL的加密与解密

题目&#xff1a; 题解&#xff1a; import "math/rand"type Codec map[int]stringfunc Constructor() Codec {return Codec{} }func (c Codec) encode(longUrl string) string {for {key : rand.Int()if c[key] "" {c[key] longUrlreturn "http:/…

德国卡赫携丰硕成果七赴进博会

第七届中国国际进口博览会于11月5日在国家会展中心&#xff08;上海&#xff09;正式拉开帷幕。作为全球最大的清洁设备和清洁解决方案提供商&#xff0c;“全勤生”德国卡赫连续七年参展&#xff0c;并携集团旗下子品牌HAWK霍克一同亮相技术装备展区3号馆&#xff0c;更带来多…

IT架构管理

目录 总则 IT架构管理目的 明确组织与职责 IT架构管理旨在桥接技术实施与业务需求之间的鸿沟&#xff0c;通过深入理解业务战略和技术能力&#xff0c;推动技术创新以支持业务增长&#xff0c;实现技术投资的最大价值。 设定目标与范围 IT架构管理的首要目的是确立清晰的组织…

Rust项目结构

文章目录 一、module模块1.文件内的module 二、模块化项目结构1.关于module2.各个模块之间互相引用 三、推荐项目结构1.实例 参考 一、module模块 1.文件内的module 关键字&#xff1a;mod 引入模块中的方法 usemod名字&#xff1a;方法名usemod名字.*写全路径 二、模块化…

HiveSQL 中判断字段是否包含某个值的方法

HiveSQL 中判断字段是否包含某个值的方法 在 HiveSQL 中&#xff0c;有时我们需要判断一个字段是否包含某个特定的值。下面将介绍几种常用的方法来实现这个功能。 一、创建示例表并插入数据 首先&#xff0c;我们创建一个名为employee的表&#xff0c;并插入一些示例数据&am…

408——计算机网络(持续更新)

文章目录 一、计算机网络概述1.1 计算机网络的概念1.2 计算机网络体系结构1.3 总结 二、物理层2.1 物理层的基本概念2.2 物理层的基本通信技术2.3 总结 三、数据链路层3.1 数据链路层基础概论3.2 数据链路层的通信协议 一、计算机网络概述 1.1 计算机网络的概念 计算机网络的定…

正反shell反弹的区分

在shell反弹中我们会根据参照物的不同来区分正反shell反弹。 本次我们需要使用win和kali进行实验&#xff1a; 在shell反弹中我们需要在win上面安装netcat&#xff08;瑞士军刀&#xff09;用于可以执行监听指令。 下载指导链接https://blog.csdn.net/qq_40359932/article/d…

CSS的配色

目录 1 十六进制2 CSS中的十六进制2.1 十六进制颜色的基本结构2.2 十六进制颜色的范围2.3 简写形式2.4 透明度 3 CSS的命名颜色4 配色4.1 色轮4.2 互补色4.3 类似色4.4 配色工具 日常在开发小程序中&#xff0c;客户总是希望你的配色是美的&#xff0c;但是美如何定义&#xff…

Java 基于SpringBoot+Vue 的公交智能化系统,附源码、文档

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

qt QFile详解

1、概述 QFile类是Qt框架中用于读取和写入文本和二进制文件资源的I/O工具类。它继承自QFileDevice类&#xff0c;后者又继承自QIODevice类。QFile类提供了一个接口&#xff0c;允许开发者以二进制模式或文本模式对文件进行读写操作。默认情况下&#xff0c;QFile假定文件内容为…

react jsx基本语法,脚手架,父子传参,refs等详解

1&#xff0c;简介 1.1 概念 react是一个渲染html界面的一个js库&#xff0c;类似于vue&#xff0c;但是更加灵活&#xff0c;写法也比较像原生js&#xff0c;之前我们写出一个完成的是分为html&#xff0c;js&#xff0c;css&#xff0c;现在我们使用react库我们把html和js结…

Qt学习笔记第41到50讲

第41讲 UI美化遗留问题解决 如上图所示目前记事本的雏形已现&#xff0c;但是还是有待优化&#xff0c;比如右下角的拖动问题。 解决方法&#xff1a; ①首先修改了Widget类的构造函数。 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) {ui->s…

Linux(VMware + CentOS )设置固定ip

需求&#xff1a;设置ip为 192.168.88.130 先关闭虚拟机 启动虚拟机 查看当前自动获取的ip 使用 FinalShell 通过 ssh 服务远程登录系统&#xff0c;更换到 root 用户 修改ip配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 重启网卡 systemctl restart network …

CAN总线学习笔记(1、CAN总线定义)

CAN总线学习笔记&#xff08;1、CAN总线定义&#xff09; 江协科技CAN总线入门教程视频学习笔记 CAN特性 两根通信线&#xff08;CAN_H\CAN_L&#xff09;,两根线&#xff0c;无需工地 差分信号&#xff0c;抗干扰能力强 高速CAN&#xff08;ISO11898&#xff09;&#xff…

伍光和《自然地理学》电子书(含考研真题、课后习题、章节题库、模拟试题)

《自然地理学》&#xff08;第4版&#xff09;由伍光和、王乃昂、胡双熙、田连恕、张建明合著&#xff0c;于2018年11月出版。作为普通高等教育“十一五”国家级规划教材&#xff0c;本书不仅适用于高校地球科学各专业的基础课程&#xff0c;还可供环境、生态等有关科研、教学人…

Idea如何推送项目到gitee

第一步&#xff1a;先在你的gitee创建一个仓库 第二步&#xff1a; 点击推送 点击定义远程&#xff0c;将URL换成你仓库的&#xff0c;填好你的用户名和密码 可以看到已经推送到仓库了