Unity之王牌飞行员申请出战

目录

📚一、准备工作

💻二、飞机的两套控制器

🎮2.1 起飞前

🕹️2.2 起飞后

🚀三、实现射击功能

💥3.1 射击脚本

💥3.2 爆炸脚本

💥3.3 爆炸特效脚本

🛠️四、组装


很久没碰Unity好多功能用法都快忘了,幸亏写了博客可以回顾看一下,这就是写笔记的好处。Unity专栏里上一篇文章是做一个会飞的超人,其实我真正想做的是飞机,终于有机会摸鱼趁着这个时间实现了,效果看下面的GIF图片,最后还来了一个迫降。

实例中有两套控制系统,分别是飞机在地上和天上两种不同的控制方式;

起飞前按住W不断加速,松开W速度会下降,加速到一定数值后按空格弹射起飞;

起飞后Q、E控制飞机旋转、空格升左Ctrl键降,鼠标控制飞行方向,鼠标左键发射子弹;

GIF很糊是压缩后的,原图有一百多M,说实话这个压缩后的画风有点像油画还挺好看的。


📚一、准备工作

用到的资源都是免费的,大家可以直接去资源商店下载

这个资源我博客讲物理系统时用到过,子弹爆炸逻辑也是和物理系统这篇文章中的小实例一样的。Unity之物理系统_unity物理系统-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_48512649/article/details/135600857这个资源中用到了飞机的尾部喷气粒子特效和子弹打到物体后的爆炸特效。

💻二、飞机的两套控制器

将飞机模型加到场景中,摄像机加到飞机模型上跟随飞机,选一个自己喜欢颜色的粒子特效加入到飞机尾部(注意朝向 —— 旋转一下粒子特效)然后我们开始编写飞行控制器脚本。

🎮2.1 起飞前

讲一下实现思路,在PlayerControl脚本中先定义一个移动速度的变量MoveSpeed,当玩家按住W时MoveSpeed会自增实现加速效果,松开W键会由加速状态变为减速状态,加速减速通过布尔型SpeedUp来控制。当加速到一定数值(自己定义)按空格键执行TackOff()方法

using UnityEngine;public class PlayerControl : MonoBehaviour
{public float MoveSpeed = 0.1f;// Start is called before the first frame updatepublic float takeOffForce = 100f; // 起飞力大小private Rigidbody rb;public ParticleSystem particleSystem;public bool SpeedUp = false;void Start(){rb = GetComponent<Rigidbody>();//particleSystem = GetComponent<ParticleSystem>();}// Update is called once per framevoid Update(){//水平轴float horizontal = Input.GetAxis("Horizontal");//垂直轴float vertical = Input.GetAxis("Vertical");//创建成一个方向向量Vector3 dir = new Vector3(horizontal, 0, vertical);//朝方向向量移动transform.Translate(dir * MoveSpeed * Time.deltaTime);  //加速if (Input.GetKey(KeyCode.W) && MoveSpeed <= 200){MoveSpeed += 0.1f;Debug.Log("__________" + MoveSpeed);SpeedUp = true;// 加速时播放飞机尾部喷气粒子特效particleSystem.Play();}if (Input.GetKeyUp(KeyCode.W)){SpeedUp = false;}if (!SpeedUp){// 减速时关闭飞机尾部喷气粒子特效particleSystem.Stop();}//减速if (MoveSpeed >= 1 && !SpeedUp){MoveSpeed -= 0.1f;Debug.Log("**********" + MoveSpeed);}// 检测玩家输入,按下空格键开始起飞if (Input.GetKeyDown(KeyCode.Space) && MoveSpeed >= 100){TakeOff();}//飞机起飞前控制器脚本启用时,重力也启用if (GetComponent<PlayerControl>().enabled){rb.useGravity = true;}}void TakeOff(){// 给飞机施加向上的力来模拟起飞rb.AddForce(Vector3.up * takeOffForce);GetComponent<PlayerControl>().enabled = false; // 关掉起飞前脚本GetComponent<FlyContro>().enabled = true;      // 启用起飞后脚本rb.useGravity = !rb.useGravity;                //起飞前使用重力,起飞后关掉重力}
}

🕹️2.2 起飞后

unity制作3维飞行_哔哩哔哩_bilibili这是飞行控制器的教程。

起飞后除了前后左右移动还增加了悬停和翻滚,打开输入管理器后Ctrl+D复制两个垂直然后改成HoverRoll


(Futura AI (bestzpr.cn)一个AI网站,这次案例实现过程中也帮了我很多)


using UnityEngine;public class FlyContro : MonoBehaviour
{//前进速度、转向速度、悬停速度public float forwardSpeed = 200f, strafeSpeed = 7.5f, hoverSpeed = 5f;//获取到玩家操作输入的前进速度、转向速度、悬停速度private float activeforwardSpeed, activeStrafeSpeed, activeHoverSpeed;//定义加速度private float forwardAcceleration = 2.5f, strafeAcceleration = 2f, hoverAcceleration = 2f;public float lookRateSpeed = 90f;private Vector2 lookInput, screenCenter, mouseDistance;private float rollInput;public float rollSpeed = 90f, rollAcceleration = 3.5f;public Rigidbody rb;// Start is called before the first frame updatevoid Start(){//屏幕中心位置screenCenter.x = Screen.width * 0.5f;screenCenter.y = Screen.height * 0.5f;Cursor.lockState = CursorLockMode.Confined;rb = GetComponent<Rigidbody>();}// Update is called once per framevoid Update(){// 记录鼠标的位置lookInput.x = Input.mousePosition.x;lookInput.y = Input.mousePosition.y;//获取到鼠标的距离mouseDistance.x = (lookInput.x - screenCenter.x) / screenCenter.y;mouseDistance.y = (lookInput.y - screenCenter.y) / screenCenter.y;//限制鼠标操控飞机朝向的速度mouseDistance = Vector2.ClampMagnitude(mouseDistance, 1f);//获取翻滚输入rollInput = Mathf.Lerp(rollInput, Input.GetAxisRaw("Roll"), rollAcceleration * Time.deltaTime);//实现鼠标控制朝向transform.Rotate(-mouseDistance.y * lookRateSpeed * Time.deltaTime, mouseDistance.x * lookRateSpeed * Time.deltaTime,rollInput * rollSpeed * Time.deltaTime, Space.Self);//获取按键输入速度activeforwardSpeed = Mathf.Lerp(activeforwardSpeed,Input.GetAxisRaw("Vertical") * forwardSpeed,forwardAcceleration * Time.deltaTime);activeStrafeSpeed = Mathf.Lerp(activeStrafeSpeed,Input.GetAxisRaw("Horizontal") * strafeSpeed,strafeAcceleration * Time.deltaTime);activeHoverSpeed = Mathf.Lerp(activeHoverSpeed,Input.GetAxisRaw("Hover") * hoverSpeed, hoverAcceleration * Time.deltaTime);//实现飞机移动transform.position += transform.forward * activeforwardSpeed * Time.deltaTime;transform.position += (transform.right * activeStrafeSpeed * Time.deltaTime) + (transform.up * activeHoverSpeed * Time.deltaTime);}//监听发生碰撞: 只监听发生碰撞的一瞬间private void OnCollisionEnter(Collision collision)  //参数 collision 就是你碰撞到的物体的碰撞信息{//当飞机落地时转换飞机的控制器 (地面设置标签为Ground)if (collision.gameObject.layer == LayerMask.NameToLayer("Ground")){Debug.Log("物体接触到指定图层标签的物体");// 在这里执行接触到指定图层标签的物体时的操作GetComponent<PlayerControl>().enabled = true; // 启用脚本GetComponent<FlyContro>().enabled = false;    // 禁用脚本//rb.useGravity = !rb.useGravity;}}
}

🚀三、实现射击功能

准备工作里我们说了射击的原理和物理系统那篇文章中的小案例是一样的

子弹发射出去(射击脚本)碰到物体子弹销毁产生爆炸特效(爆炸脚本),爆炸特效完成后爆炸物消失(爆炸特效脚本)


💥3.1 射击脚本

编写射击脚本Shoot

using UnityEngine;public class Shoot : MonoBehaviour
{// Start is called before the first frame update//子弹预设体序列化[SerializeField]private GameObject bulletPrefab;//游戏对象子弹发射点[SerializeField]private GameObject bulletPoint1;//游戏对象子弹发射点[SerializeField]private GameObject bulletPoint2;//子弹速度[SerializeField] private float bulletSpeed = 10000000;void Start(){}// Update is called once per framevoid Update(){//是否持续按下鼠标if (Input.GetMouseButton(0) && GetComponent<FlyContro>().enabled){GameObject bullet1 = Instantiate(bulletPrefab, bulletPoint1.transform.position, transform.rotation);GameObject bullet2 = Instantiate(bulletPrefab, bulletPoint2.transform.position, transform.rotation);//给子弹一个向前的力bullet1.GetComponent<Rigidbody>().AddForce(transform.forward * bulletSpeed * Time.deltaTime);bullet2.GetComponent<Rigidbody>().AddForce(transform.forward * bulletSpeed * Time.deltaTime);//3秒后销毁子弹Destroy(bullet1,3);Destroy(bullet2,3);}}
}

💥3.2 爆炸脚本

编写子弹打到物体后爆炸脚本Bomb

public class Bomb : MonoBehaviour
{//创建一个爆炸的预设体public GameObject Prefab;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}//监听发生碰撞: 只监听发生碰撞的一瞬间private void OnCollisionEnter(Collision collision)  //参数 collision 就是你碰撞到的物体的碰撞信息{if (collision.gameObject.name == "Bullet(Clone)"){return;}//创建一个爆炸物体Instantiate(Prefab, transform.position, Quaternion.identity);   //参数: 预设体,爆炸位置是自身位置,不旋转//销毁自身: 子弹撞击地面爆炸物产生子弹销毁Destroy(gameObject);//获取碰撞到物体看一下参数collision —— 打印一下物体名称,这里打印的是地面的名称Debug.Log(collision.gameObject.name);}
}

💥3.3 爆炸特效脚本

编写爆炸物特效脚本Explosion

using UnityEngine;public class Explosion : MonoBehaviour
{float timer = 0;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){//如果时间大于一秒就销毁爆炸物timer += Time.deltaTime;if (timer > 1){Destroy(gameObject);}}
}

🛠️四、组装

子弹我是用球体做的拉伸成长条状,给子弹挂载Bomb脚本、碰撞组件、刚体

 飞机挂载刚体、碰撞组件、两个控制器脚本(默认飞行前控制器启用、飞行后控制器禁用),在飞机模型上创建两个空物体作为发射点(注意:飞机发射点要调整到子弹和飞机不能相撞的位置),挂载射击脚本把子弹预设物、发射点、子弹速度设置好。

爆炸特效也装上脚本

对了,鼠标图标是我自己找的一个icon,大家可以自己找一个喜欢的自己设置

到这里基本就结束了,不过我们还可以给飞机加上血条,我们也学习了PUN插件可以联机,嗯?奇怪的想法又增加了。

本篇先到这里,感谢大家支持求三连,拜拜┏(^0^)┛ 

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

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

相关文章

AGE 可比性、相等性、可排序性和等效性

AGE已经对原始类型&#xff08;布尔值、字符串、整数和浮点数&#xff09;和映射的相等性有了良好的语义。此外&#xff0c;Cypher对整数、浮点数和字符串的可比性和可排序性也有很好的语义。然而&#xff0c;处理不同类型的值与Postgres定义的逻辑和openCypher规范存在偏差&am…

Linux_网络编程_TCP

服务器客户端模型&#xff1a; client / server brow / ser b / s http p2p socket——tcp 1、模式 C/S 模式 》服务器/客户端模型 server :socket()-->bind()--->listen()-->accept()-->recv()-->close()client :socket()-->conn…

STM32第九课:STM32-基于标准库的42步进电机的简单I/O控制(附电机教程,看到即赚到)

一&#xff1a;步进电机简介 步进电机又称为脉冲电机&#xff0c;简而言之&#xff0c;就是一步一步前进的电机。基于最基本的电磁铁原理,它是一种可以自由回转的电磁铁,其动作原理是依靠气隙磁导的变化来产生电磁转矩&#xff0c;步进电机的角位移量与输入的脉冲个数严格成正比…

超越单兵作战:多智能体 Multi-Agent System (MAS)

超越单兵作战&#xff1a;多智能体 Multi-Agent System (MAS) Multi-Agent System 是指一个系统中有多个智能体同时工作的情况。在这样的系统中&#xff0c;每个智能体都具有一定程度的自主性&#xff0c;可以独立执行任务、做决定&#xff0c;并且能够与其他智能体进行交互&a…

STM32的Code、RO-data、RW-data、ZI-data和RAM以及flash的关系

对于刚接触stm32编程的同学来说&#xff0c;通常不知道如何选择合适型号的芯片来开发自己的项目&#xff0c;下面就分析一下多大的片内ram以及flash能符合我们项目的需求。 不知道大家有没有注意到&#xff0c;我们的项目每次编译完成后&#xff0c;都会出现这个Program Size&…

亚马逊卖家告别熬夜!批量定时上下架,自动调价

必用能功三个&#xff0c;不限制上传商品。 大家好&#xff0c;今天来讲下这款erp的定时上下架功能。 打开工具这栏选择智能调价&#xff0c;点击添加智能调价选择店铺&#xff0c;选择定时上架的商品添加也可以全部添加。每个商品的价格都是不同的&#xff0c;可以点击保底价…

windows10开启防火墙,增加入站规则后不生效,还是不能访问后端程序

一、背景&#xff1a; 公司护网要求开启防火墙&#xff0c;开启防火墙后&#xff0c;前后端分离的项目调试受影响&#xff0c;于是增加入站规则开放固定的后台服务端口&#xff0c;增加的mysql端口3306和redis端口6379&#xff0c;别人都可以访问&#xff0c;但是程序的端口808…

抖音工具箱功能菜单解析分享

一 支持视频链接 采集/点赞/评论/收藏 二 支持导入 用户id私信 内容自定义 可 关注后私信对方 私信间隔自定义 三 支持多直播间 发言 内容-间隔自定义 五 支持 监听指定用户作品 新发作品 自动 点赞/评论/收藏 六 支持 视频评论实时监控 新发评论自动采集获取 七 智能 暂停…

NLP入门——卷积语言模型的搭建、训练与预测

语言模型建模是针对句子建模&#xff0c;主要分为掩码语言模型和自回归语言模型。 我们从corpus中截取一句话作为例子&#xff0c;这句话是bpe分词后的句子&#xff1a; 1994 年 5 月 17 日 安全 理事会 第 33 77 次 会议 通过 掩码语言模型的主要机制是&#xff1a;例如将33 7…

PostgREST API 安装及基础使用

PostgREST是一个独立的Web服务器&#xff0c;它将PostgreSQL数据库转换为RESTful API。它提供基于基础数据库的结构自定义的API。 PostgREST安装 首先访问Releases PostgREST/postgrest (github.com)&#xff0c;根据安装平台选择下载的源码。比如我现在的设备是Mac但是我的…

删掉此电脑中烦人的百度网盘、WPS、迅雷下载图标(还有导航栏)-win10/11

删掉此电脑的图标 1、首先 搜索 注册表管理器 或者 win R 输入 regedit 2、在红框的地方输入这串路径&#xff08;下2选1&#xff09;&#xff1a; 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\ HKEY_CURRENT_US…

【C++】使用C++实现基于Socket的通信

在本文中&#xff0c;我们将详细讨论如何使用C实现基于Socket的通信&#xff0c;并设计一个TLV&#xff08;Type-Length-Value&#xff09;协议用于数据交互。TLV协议因其灵活性和可扩展性&#xff0c;在多种通信协议中被广泛使用&#xff0c;特别是在需要动态定义数据结构的场…

【Axure】产品原型如何在谷歌浏览器中打开

作为一名前端开发来说&#xff0c;在拿到产品的原型图后&#xff0c;如何打开&#xff1f;直接用谷歌浏览器打开&#xff0c;是打不开的&#xff0c;需要安装对应的插件。但是谷歌插件市场在不翻墙的情况下&#xff0c;是没有办法直接打开的&#xff0c;分享一种超级简单的方法…

深入解析RocketMQ的名字服务机制:功能、原理与应用

NameServer 是专为 RocketMQ 设计的轻量级名字服务&#xff0c;它的源码非常精简&#xff0c;八个类 &#xff0c;少于 1000 行代码。 这篇文章&#xff0c; 笔者会从基础概念、Broker 发送心跳包、NameServer 维护路由、Zookeeper vs NameServer 四个模块揭秘名字服务的设计精…

电脑怎样连接打印机?详细步骤告诉你!

在现代办公环境中&#xff0c;打印机是必不可少的设备之一。无论是打印文档、图片还是其他资料&#xff0c;连接打印机都是我们日常工作中的基本操作。然而&#xff0c;不同类型的打印机和连接方式可能会让人感到困惑。本文将介绍电脑怎样连接打印机的3种方法&#xff0c;帮助您…

简易限流实现

需求描述 写一个1秒两个的限流工具类&#xff0c;2r/s 使用semaphore 代码实现-类似令牌桶算法 public class LimitHelper {private int maxLimit;private Semaphore semaphore;private int timeoutSeconds;public LimitHelper(int maxLimit, int timeoutSeconds) {this.max…

LNMP搭建Discuz和Wordpress

1、LNMP L:linux操作系统 N&#xff1a;nginx展示前端页面web服务 M&#xff1a;mysql数据库&#xff0c;保存用户和密码&#xff0c;以及论坛相关的内容 P&#xff1a;php动态请求转发的中间件 数据库的作用&#xff1a; 登录时验证用户名和密码 创建用户和密码 发布和…

昇思25天学习打卡营第十七天|文本解码原理--以MindNLP为例

背景 提供免费算力支持&#xff0c;有交流群有值班教师答疑的华为昇思训练营进入第十七天了。 今天是第十七天&#xff0c;从第十天开始&#xff0c;进入了应用实战阶段&#xff0c;前九天都是基础入门阶段&#xff0c;具体的学习内容可以看链接 基础学习部分 昇思25天学习打卡…

Unity发布webgl之后修改StreamingAssets 内的配置文件读取到的还是之前的配置文件的解决方案

问题描述 unity发布webgl之后&#xff0c;修改在StreamingAssets 中的配置信息&#xff0c;修改之后读取的还是之前的配置信息 读取配置文件的代码IEnumerator IE_WebGL_LoadWebSocketServerCopnfig(){var uri new System.Uri(Path.Combine(Application.streamingAssetsPath…

居家客服人员分散,更需要统一客服话术

1、居家客服服务需求激增 近年来&#xff0c;随着线上消费的兴起&#xff0c;以及客服人员成本的不断攀升&#xff0c;越来越多的企业选择雇佣居家客服&#xff0c;以客服服务发包的形式接待客户的咨询。因此&#xff0c;居家客服人员的数量也逐渐增加。然而&#xff0c;居家办…