【unity之IMGUI实践】敌方逻辑封装实现【六】
👨💻个人主页:@元宇宙-秩沅
👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!
👨💻 本文由 秩沅 原创
👨💻 收录于专栏:unityUI专题篇
⭐通用API实现抽象行为封装【五】⭐
文章目录
- ⭐通用API实现抽象行为封装【五】⭐
- 🎶前言
- 🎶(==A==)UML
- 🎶(==B==)需求分析
- 🎶(==C==)行为实现——炮台的自动检测并攻击
- 🎶(==D==)行为实现——敌军坦克的移动路线和检测攻击
- 总结:
🎶前言
🅰️
🎶(A)UML
🎶(B)需求分析
🎶(C)行为实现——炮台的自动检测并攻击
😶🌫️:步骤实现
1.炮台的行为逻辑封装:旋转,触发检测,发射炮弹及特效
2.检测玩家后自动瞄准攻击
3.玩家扣血,更新血条,触发保护罩特效及死亡
——————————————
涉及到四个脚本
炮台封装
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目: ______________
//___________功能: 炮台的行为逻辑实现
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class battery : TankFather
{public AudioSource shootMusic; //发射音效public GameObject shootball; //发射的子弹类型public float shootSpeed = 1000f; //子弹的速度 public Transform shootTransform; //发射的组件信息public bool shootSwitch = false;//射击检测参数public Transform player; //闯入者private float endTime = 8f; //子弹发射间隔的时间private void Start(){//属性初始化赋值Head = transform.GetChild(0);maxBlood = 500;nowBlood = 500;attack = 20; HeadSpeed = 50;//射击音效关闭shootMusic.enabled = false;}private void Update(){ if (shootSwitch == false) //不停的旋转{Head.transform.Rotate(Vector3.up * HeadSpeed * Time.deltaTime);} else {Head.transform.LookAt(player);//倒计时发射子弹endTime = Mathf.MoveTowards(endTime, 0, 0.1f);if(endTime <= 0){Fire();endTime = 3f;}} }//玩家进入范围内就开始射击private void OnTriggerEnter(Collider other){if(other.tag == "Player"){shootSwitch = true;player = other.transform;}}//受伤检测private void OnTriggerStay(Collider other){float off = Vector3.Distance(other.transform.position, transform.position);if (other.gameObject.tag == "bullet" && off < 2){//添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合BulletMove ball = other.gameObject.GetComponent<BulletMove>();TankFather ballTank = ball.Tank.GetComponent<TankFather>();//当子弹不是自己打的到自己身上的时候if (ballTank.tag != gameObject.tag){//扣血Heart(ballTank);}}}//玩家出去后就停止射击private void OnTriggerExit(Collider other){if (other.tag == "Player"){shootSwitch = false;}}//开火重写public override void Fire(){//开启射击音效shootMusic.enabled = true;shootMusic.Play();GameObject ball = Instantiate(shootball, shootTransform.position , shootTransform.rotation);BulletMove movScript = ball.GetComponent<BulletMove>();Rigidbody shootBall = ball.GetComponent<Rigidbody>();shootBall.AddForce(shootTransform .transform.forward * shootSpeed );movScript.Tank =gameObject ; //声明子弹是由谁打出去的}}
坦克基类更新
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:
//___________功能: 坦克基类——集中子类相同点
//___________创建者:______秩沅______
//___________________________________
//-------------------------------------
public abstract class TankFather : MonoBehaviour
{//攻击和防御相关public int attack;public int defence; public float nowBlood;public float maxBlood;//移动和转速相关public int moveSpeed;public int RotateSpeed;public int HeadSpeed;public Transform Head;//击败特效public GameObject diedEffect;//收到伤害打开保护罩的特效public GameObject ProtectEffectMain;public GameObject ProtectEffectOther;private void Awake(){// ProtectEffectMain = Resources.Load<GameObject>(@"Prefabs/OherResoure/Protect1");// ProtectEffectOther = Resources.Load<GameObject>(@"Prefabs/OherResoure/Protect2");}//受伤行为public virtual void Heart(TankFather other){//当攻击力大于防御力时才生效if (other.attack - defence > 0){nowBlood -= (other.attack - defence);}if (nowBlood <= 0){nowBlood = 0;Death();}if (gameObject.tag == "Player")//如果是主玩家才更新血条{//更新血条GamePlane.SingleInstance.UpdataBlood(maxBlood, nowBlood);//实例化保护罩的特效 GameObject eff = Instantiate(ProtectEffectMain, transform.position, transform.rotation);Destroy(eff,1f);}}//死亡行为public virtual void Death(){//将特效实例化相关逻辑GameObject effect = Instantiate(diedEffect, this.transform.position ,this.transform.rotation);AudioSource soudClip = effect.GetComponent<AudioSource>();soudClip.enabled = MusicContol.SingleMusicContol.nowMusicData.soundSwitch;soudClip.volume = MusicContol.SingleMusicContol.nowMusicData.soundRoll ;soudClip.mute = false;soudClip.playOnAwake = true;//死亡后展示死亡面板if (gameObject.tag == "Player"){Destroy(gameObject, 2F);DiedPlane.SingleInstance.Show();}elseDestroy(gameObject);}//开火行为public abstract void Fire(); //子类中每一个的开火方式都不同,作为抽象方法}
主坦克类更新
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:
//___________功能: 坦克的移动和旋转
//___________创建者:_______秩沅_______
//_____________________________________
//-------------------------------------
public class MainTank : TankFather
{//主坦克专有特征public Weapon nowWeapon;//特征属性初始化private void Awake(){Head = transform.GetChild(1).GetChild(0);maxBlood = 1000;nowBlood = 1000;attack = 30;defence = 10;moveSpeed = 5;RotateSpeed = 50;HeadSpeed = 500;}private void Update(){//坦克的移动 = 大小*方向transform.Translate(Input.GetAxis("Vertical") *Vector3.forward*moveSpeed *Time.deltaTime );//坦克的旋转 = 大小*轴向transform.Rotate(Input.GetAxis("Horizontal") *Vector3.up *RotateSpeed *Time .deltaTime );//头部炮管的旋转 = 大小*轴向Head.Rotate(Input.GetAxis ("Mouse X") *Vector3.up*HeadSpeed*Time .deltaTime );//左键发射炮弹if(Input.GetMouseButtonDown(0)){Fire();}}//捡武器行为public void ChangeWeapon(GameObject weapon){if (nowWeapon != null) nowWeapon.Vanish(); //销毁当前武器nowWeapon = weapon.GetComponent<Weapon>(); //头部留有存放武器的位置weapon.gameObject.transform.position = Head.GetChild(0).transform.position ;weapon.gameObject.transform.rotation = Head.GetChild(0).transform.rotation;weapon.gameObject.transform.SetParent(Head.GetChild(0));attack += nowWeapon.attack;}//开火行为重写public override void Fire() {nowWeapon.Shoot(); }//被子弹打到private void OnTriggerEnter(Collider other){if(other.tag == "bullet"){try{//添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合BulletMove ball = other.GetComponent<BulletMove>();TankFather ballTank = ball.Tank.GetComponent<TankFather>();//当子弹不是自己打的到自己身上的时候if (ballTank.tag != "Player"){//扣血Heart(ballTank);}}catch{throw;}}}}
子弹发射更新
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目: ______________
//___________功能: 子弹的逻辑相关
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class BulletMove : MonoBehaviour
{public GameObject Tank; //挂载在哪个坦克上public GameObject DeidEffect;public AudioSource distorySound; //销毁的音效private void Start(){}//子弹的销毁及特效private void OnTriggerEnter(Collider other){if (other.CompareTag("Environment")|| other.CompareTag("Enemy")){if (DeidEffect != null){GameObject eff = Instantiate(DeidEffect, transform.position, transform.rotation);//音效控制distorySound = eff.GetComponent<AudioSource>();distorySound.enabled = MusicContol.SingleMusicContol.nowMusicData.soundSwitch;distorySound.volume = MusicContol.SingleMusicContol.nowMusicData.soundRoll;eff.AddComponent<SelfDestroy>();}Destroy(this.gameObject,2f); } }}
🎶(D)行为实现——敌军坦克的移动路线和检测攻击
😶🌫️:步骤实现
- 1.指定移动位置,设置朝向
- 2.行为逻辑封装。开火,受伤
- 3.自动检测闯入者
———— --------------————
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//-------------------------------------
//—————————————————————————————————————
//___________项目:
//___________功能:敌方坦克逻辑封装
//___________创建者:秩沅_______________
//_____________________________________
//-------------------------------------
public class EnemyTank:TankFather
{//随机移动点的位置数组public Transform[] randomPosition;//目标位置private Transform target;//目标坦克public Transform Player;//检测范围public float distance = 10f;public AudioSource shootMusic; //发射音效public GameObject shootball; //发射的子弹类型public float shootSpeed = 1000f; //子弹的速度 public Transform[] shootTransform; //发射的组件信息public bool shootSwitch = false; private float endTime = 3f; //子弹发射间隔的时间private void Start(){//属性初始化赋值maxBlood = 500;nowBlood = 500;attack = 30;HeadSpeed = 50;//射击音效关闭shootMusic.enabled = false;moveSpeed = 10f;//先随机整一个目标点RandomPosition();}private void Update(){ transform.LookAt(target);//始终超自己的正方向移动transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime); //当距离差不多相等时,再随机目标点if(Vector3.Distance(transform .position ,target .position)< 0.5f){RandomPosition();}//范围检测if (Vector3 .Distance(transform .position ,Player.position )<= distance && Player !=null ){//炮口瞄准玩家Head.transform.LookAt(Player);//倒计时发射子弹endTime = Mathf.MoveTowards(endTime, 0, 0.1f);if (endTime <= 0){Fire();endTime = 3f;} }}//随机指向一个移动点public void RandomPosition(){if (randomPosition.Length != 0)target = randomPosition[Random.Range(0, randomPosition.Length)];}//触发检测private void OnTriggerEnter(Collider other){if (other.gameObject.tag == "bullet" ){//添加子弹挂载的目标坦克,方便获取该子弹的攻击力,与受伤逻辑相结合BulletMove ball = other.gameObject.GetComponent<BulletMove>();TankFather ballTank = ball.Tank.GetComponent<TankFather>();//当子弹不是自己打的到自己身上的时候if (ballTank.tag != gameObject.tag){//扣血Heart(ballTank);}}}public override void Fire(){//开启射击音效shootMusic.enabled = true;shootMusic.Play();for (int i = 0; i < shootTransform.Length ; i++){GameObject ball = Instantiate(shootball, shootTransform[i].position, shootTransform[i].rotation);BulletMove movScript = ball.GetComponent<BulletMove>();Rigidbody shootBall = ball.GetComponent<Rigidbody>();shootBall.AddForce(shootTransform[i].transform.forward * shootSpeed);movScript.Tank = gameObject; //声明子弹是由谁打出去的}}}
问题:
1.受到伤害,开启了保护罩但是不扣血
2.敌方坦克,原地打转,未按规定路线移动
解决:
1.子弹检测逻辑错误
2.位置空点绑定在对象身上变成了子对象因此无法达到效果
总结:
- 1.检测触发的方式:①触发器检测②向量距离检测
- 2.多点指定移动,加入向量距离判断,重合的机率小,故此不能 A物体距离 == B物体距离
- 3.子坦克继承了父类脚本,引用传递时直接用父类即可获得该子类,(原因父类名字相同,但是子类名字不同,无法确定,所以里氏替换作用在此体现)
⭐相关文章⭐
⭐【2023unity游戏制作-mango的冒险】-6.关卡设计
⭐【2023unity游戏制作-mango的冒险】-5.攻击系统的简单实现
⭐【2023unity游戏制作-mango的冒险】-4.场景二的镜头和法球特效跟随
⭐【2023unity游戏制作-mango的冒险】-3.基础动作和动画API实现
⭐【2023unity游戏制作-mango的冒险】-2.始画面API制作
⭐【2023unity游戏制作-mango的冒险】-1.场景搭建
⭐“狂飙”游戏制作—游戏分类图鉴(网易游学)
⭐本站最全-unity常用API大全(万字详解),不信你不收藏
你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!
相关文章:

【unity之IMGUI实践】敌方逻辑封装实现【六】
👨💻个人主页:元宇宙-秩沅 👨💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨💻 本文由 秩沅 原创 👨💻 收录于专栏:uni…...
llvm向用户抛出warning、error信息
1、抛出error信息并终止程序 使用DiagnosticInfoUnsupported可以向用户抛出error信息并且终止程序,效果如同report_fatal_error、Error。后端用法如下: void xxxx::reportErrorMsg(const MachineFunction &MF)const {const Function &F MF.ge…...

微服务学习笔记-----Nacos安装教程(Windows和Linux版本)
Nacos安装教程 Nacos安装指南1.Windows安装1.1.下载安装包1.2.解压1.3.端口配置1.4.启动1.5.访问 2.Linux安装2.1.安装JDK2.2.上传安装包2.3.解压2.4.端口配置2.5.启动 3.Nacos的依赖 Nacos安装指南 1.Windows安装 开发阶段采用单机安装即可。 1.1.下载安装包 在Nacos的Git…...
程序员面试系列,docker常见面试题
原文链接 什么是Docker?它的主要作用是什么?Docker和虚拟机之间有什么区别?Docker的主要组件有哪些?Docker镜像和容器的区别是什么?如何构建Docker镜像?请简要描述构建过程。如何创建和启动一个Docker容器…...

Linux centos7.x系统将/home磁盘分配给/
1.解除挂载并删除/home卷 umount /home如果出现以下报错 : 可以使用以下命令查看哪些进程在占用 fuser -mv /home杀死这些进程就行 kill -9 进程号然后再执行umount /home就可以成功了 , 同时执行以下命令把逻辑卷删除了 lvremove /dev/centos/home…...
根据数组元素为对象,对元素对象的某一属性进行排序
前言: 开发过程中,前端难免需要对数据进行操作,比如比较常见的操作就是对数组元素进行排序 对数组元素对基本类型的进行排序 const arr [2,4,1,3,9,5]arr.sort((a,b)>a-b) //[1, 2, 3, 4, 5, 9] arr.sort((a,b)>b-a) //[9, 5, 4, 3,…...

mysql(三)用户权限管理
目录 前言 一、概述 二、用户权限类型 三、用户赋权 四、权限删除 五、删除用户 前言 为什么要设置用户权限? MySQL设置用户管理权限的主要目的是为了确保数据库的安全性和数据的机密性。以下是一些原因: 1. 安全性:MySQL是一个开源的关系型…...
字节JAVA岗位面试总结汇总
主要拷打了 redis+mysql+网络+系统+java+算法,面试问题主要集中在 mysql、redis、网络这三部门, Redis 相关 介绍一下redis数据库? Redis 是一种基于内存的数据库,对数据的读写操作都是在内存中完成,因此读写速度非常快,常用于缓存,消息队列、分布式锁等场景。 Redis…...
29-使用RocketMQ做削峰处理
1、初识RocketMQ 1.1、Apache 下载RocketMQ https://downloads.apache.org/rocketmq/ 1.2、RocketMQ官方网站 https://rocketmq.apache.org/zh/ 1.3、RocketMQ在GitHub文档 https://github.com/alibaba/spring-cloud-alibaba/wiki/RocketMQ 1.4、RocketMQ官方网站文档 …...

ELK 使用kibana查询和分析nginx日志
背景:使用kibana查询和分析nginx请求日志,方便开发人员查询系统日志和分析系统问题。 setp 1、定义Index patterns 2、定义Discover(Search 查询数据) 3、定义Visualizations 3.1 定义Vertical Bar 3.2 、Choose a source 3.3、定义图表 4、定义…...
mybatisplus自定义xml的sql语句进行自动分页
1、xxxMapper.xml定义 <select id"leftJoinPageList" resultMap"MonitoringDataResult"parameterType"com.ktt.carbon.verification.domain.bo.MonitoringDataBo">SELECT d.* from carbon_monitoring_data d LEFT JOIN carbon_monitoring…...
ChatGPT:人工智能开启智能交流新篇章
一、ChatGPT:智能交流的新里程碑 ChatGPT是OpenAI基于GPT技术的最新版本,采用深度学习模型,通过预训练和微调的方式,使其能够理解和生成自然语言,从而实现与人类更自然、流畅的对话和交流。 二、ChatGPT的技术原理与优…...

关于anki的一些思考
文章目录 通常情况下选择什么模板制卡?一张填空卡片的填空数量到底要多少才合适? 通常情况下选择什么模板制卡? 通常情况是指知识是以一段文字的形式呈现,而不是这些:单词、选择题、成语等(这些都可以定制…...

【动态规划刷题 1 】 第N个泰波那契数 三步问题
第N个泰波那契数 链接: 第N个泰波那契数 1137 . 第 N 个泰波那契数 泰波那契序列 Tn 定义如下: T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n,请返回第 n 个泰波那契数 Tn 的值。 示例 1: 输入:…...

【踩坑】三种方式解决 Homebrew failing to install - fatal: not in a git directory
问题描述 解决方法一 添加安全目录,没有测试。 git config --global --add safe.directory /opt/homebrew/Library/Taps/homebrew/homebrew- git config --global --add safe.directory /opt/homebrew/Library/Taps/homebrew/homebrew-cask 解决方法二 取消挂载这…...

零信任安全解决方案
什么是零信任 零信任网络架构 (ZTNA) 或零信任安全是一种新的组织网络安全方法。它旨在修复传统基于边界的安全性中的缺陷并简化网络设计。 它以“永不信任,始终验证”的原则运作。这意味着,无论用户或设备位于何处,…...

如何创建高级 CSS 下拉菜单
效果展示 实现思路及部分代码 1、定义整体页面结构 从上述的效果展示图可以看出,页面的整体结构应该需要一个总菜单容器来装载父级菜单项,并且对应的父级菜单项应该有对应的菜单子项。子菜单是分类的话,我们还需要额外在扩展对应的容器来装…...

java中判断list是否为空
java中判断list是否为空是日常代码中经常遇到的问题。最近发现一个Utils提供的方法可以一步判断。 废话不多说,直接上代码! ArrayList<String> arrayList new ArrayList<>(); System.out.println("集合1:" Collecti…...

龙芯3A5000板卡在高性能工作站的应用方案-迅为电子
将龙芯3A5000应用于高性能工作站时,可以考虑以下方案: 多核计算能力:龙芯3A5000拥有多核心处理器,具备强大的计算能力。在高性能工作站中,可以利用多核心的处理能力来支持复杂的工程设计、科学计算和数据处理任务。…...
WebSocket心跳机制
WebSocket是HTML5开始提供的一种浏览器与服务器进行全双工通讯的网络技术,属于应用层协议。 WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。 1、创建webSocket // Create WebSocket connection. const sock…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...