当前位置: 首页 > news >正文

【unity实战】用unity实现一个简易的战斗飞机控制器

文章目录

  • 前言
  • 实战
    • 1、素材
    • 2、给飞机添加刚体和碰撞器
    • 3、添加虚拟相机控制
    • 4、获取输入
    • 5、推进力
    • 6、添加升力
    • 7、添加地面检测
    • 8、转向和机身倾斜效果
    • 9、 螺旋桨旋转效果
    • 10、 UI显示速度和高度信息
    • 11、 根据速度动态播放音效大小
  • 最终代码
  • 专栏推荐
  • 完结

前言

本文介绍了Unity飞机模拟控制系统的实现方法,通过刚体物理、射线检测和欧拉角变换等技术,实现了包括起飞加速、俯仰滚转、高度速度显示等完整的飞行模拟功能,所有参数均可通过Inspector面板调节,最终呈现流畅的飞行体验效果。

实战

1、素材

https://assetstore.unity.com/packages/3d/vehicles/air/rusty-plane-161892
在这里插入图片描述

2、给飞机添加刚体和碰撞器

在这里插入图片描述

3、添加虚拟相机控制

具体可以参考:【unity知识】最新的虚拟相机Cinemachine3简单使用介绍
在这里插入图片描述

4、获取输入

#region 处理玩家输入控制
private Vector2 _movement;           // 输入控制向量
/// <summary>
/// 处理玩家输入控制
/// </summary>
private void HandleInputs()
{// 获取摇杆/键盘输入_movement.x = Input.GetAxis("Horizontal");  // 偏航控制_movement.y = Input.GetAxis("Vertical");    // 俯仰控制
}
#endregion

5、推进力

#region 推进力
[Header("推进力")]
[Tooltip("油门调节速率")]
public float throttleIncrement = 0.1f;[Tooltip("最大推进力")]
public float maxThrust = 200f;
private float throttle; // 当前使用的最大引擎推力百分比void ThrottleControl(){// 油门控制(空格加速/Ctrl减速)if (Input.GetKey(KeyCode.Space)) throttle += throttleIncrement;else if (Input.GetKey(KeyCode.LeftControl)) throttle -= throttleIncrement;// 限制油门范围并标准化throttle = Mathf.Clamp(throttle, 0f, 100f);
}void PropulsiveForce()
{// 推进力(与油门成正比)rb.AddForce(transform.forward * maxThrust * throttle);
}
#endregion

效果
在这里插入图片描述

6、添加升力

#region 升力
[Header("升力系数")]
public float lift = 135f;
void LiftForce()
{// 动态升力(速度越快升力越大)rb.AddForce(transform.up * rb.linearVelocity.magnitude * lift);
}
#endregion

在这里插入图片描述

7、添加地面检测

#region 环境检测系统
[Header("地面检测设置")]
public LayerMask groundLayer;    // 地面碰撞层
public float groundCheckDistance = 5f;  // 检测距离[Tooltip("是否处于地面状态")]
public bool isGround;            // 地面状态标识private RaycastHit _hit;         // 射线检测结果/// <summary>
/// 地面接触检测(向下发射射线)
/// </summary>
void HandleGroundCheck()
{isGround = Physics.Raycast(transform.position + new Vector3(0,1,1),transform.TransformDirection(Vector3.down),out _hit,groundCheckDistance,groundLayer);
}// 编辑器可视化辅助
void OnDrawGizmosSelected()
{Gizmos.color = Color.red;Gizmos.DrawLine(transform.position + new Vector3(0,1,1),transform.position + new Vector3(0,1,1) + transform.TransformDirection(Vector3.down) * groundCheckDistance);
}
#endregion

8、转向和机身倾斜效果

#region 转向
[Header("转向参数")][Tooltip("飞行操控灵敏度系数")]
public float responsiveness = 500f;/// <summary>
/// 偏航控制(绕Y轴旋转)
/// </summary>
void Turn()
{if (isGround) return;rb.AddTorque(transform.up * _movement.x * responsiveness);
}
#endregion#region 飞行控制系统
[Header("飞行姿态参数")]
public float maxPitchAngle = 20f;    // 最大俯仰角度
public float maxRollAngle = 30f;     // 最大滚转角度private Vector2 _currentTiltAngle;    // 当前姿态角度/// <summary>
/// 机身倾斜效果(根据输入平滑过渡)
/// </summary>
void Tilting()
{if (isGround) return;// 俯仰角度插值_currentTiltAngle.y = Mathf.Lerp(_currentTiltAngle.y,_movement.y * maxPitchAngle,Time.deltaTime * responsiveness);// 滚转角度插值_currentTiltAngle.x = Mathf.Lerp(_currentTiltAngle.x,_movement.x * maxRollAngle,Time.deltaTime * responsiveness);// 应用欧拉角旋转(保持当前偏航角)transform.localRotation = Quaternion.Euler(_currentTiltAngle.y,transform.localEulerAngles.y,-_currentTiltAngle.x);
}
#endregion

效果
在这里插入图片描述

9、 螺旋桨旋转效果

#region 螺旋桨旋转效果
[Header("螺旋桨")]
[SerializeField]
private Transform propella;
void PropellerRotation()
{// 螺旋桨旋转效果(转速与油门正相关)propella.Rotate(Vector3.right * throttle * 1000f * Time.deltaTime);
}
#endregion

在这里插入图片描述

10、 UI显示速度和高度信息

#region UI显示
[Header("UI显示")]
[SerializeField]
private Text hud;/// <summary>
/// 更新飞行数据HUD显示
/// </summary>
private void UpdateHUD()
{hud.text = $"油门: {throttle * 100:F0}%\n" +$"空速: {rb.linearVelocity.magnitude * 3.6f:F0} km/h\n" +$"高度: {transform.position.y:F0} m";
}
#endregion

效果
在这里插入图片描述

11、 根据速度动态播放音效大小

#region 音效
void PlaySound()
{audioSource.volume = throttle * 0.01f;
}
#endregion

最终代码

using UnityEngine;
using UnityEngine.UI;public class PlaneController : MonoBehaviour
{private Rigidbody rb;private AudioSource audioSource;private void Start(){rb = GetComponent<Rigidbody>();audioSource = GetComponent<AudioSource>();}private void Update(){HandleGroundCheck();ThrottleControl();HandleInputs();Tilting();PropellerRotation();UpdateHUD();PlaySound();}private void FixedUpdate(){PropulsiveForce();Turn();LiftForce();}#region 处理玩家输入控制private Vector2 _movement;           // 输入控制向量/// <summary>/// 处理玩家输入控制/// </summary>private void HandleInputs(){// 获取摇杆/键盘输入_movement.x = Input.GetAxis("Horizontal");  // 偏航控制_movement.y = Input.GetAxis("Vertical");    // 俯仰控制}#endregion#region 推进力[Header("推进力")][Tooltip("油门调节速率")]public float throttleIncrement = 0.1f;[Tooltip("最大推进力")]public float maxThrust = 200f;private float throttle; // 当前使用的最大引擎推力百分比void ThrottleControl(){// 油门控制(空格加速/Ctrl减速)if (Input.GetKey(KeyCode.Space)) throttle += throttleIncrement;else if (Input.GetKey(KeyCode.LeftControl)) throttle -= throttleIncrement;// 限制油门范围并标准化throttle = Mathf.Clamp(throttle, 0f, 100f);}void PropulsiveForce(){// 推进力(与油门成正比)rb.AddForce(transform.forward * maxThrust * throttle);}#endregion#region 升力[Header("升力系数")]public float lift = 135f;void LiftForce(){// 动态升力(速度越快升力越大)rb.AddForce(transform.up * rb.linearVelocity.magnitude * lift);}#endregion#region 转向[Header("转向参数")][Tooltip("飞行操控灵敏度系数")]public float responsiveness = 500f;/// <summary>/// 偏航控制(绕Y轴旋转)/// </summary>void Turn(){if (isGround) return;rb.AddTorque(transform.up * _movement.x * responsiveness);}#endregion#region 飞行控制系统[Header("飞行姿态参数")]public float maxPitchAngle = 20f;    // 最大俯仰角度public float maxRollAngle = 30f;     // 最大滚转角度private Vector2 _currentTiltAngle;    // 当前姿态角度/// <summary>/// 机身倾斜效果(根据输入平滑过渡)/// </summary>void Tilting(){if (isGround) return;// 俯仰角度插值_currentTiltAngle.y = Mathf.Lerp(_currentTiltAngle.y,_movement.y * maxPitchAngle,Time.deltaTime * responsiveness);// 滚转角度插值_currentTiltAngle.x = Mathf.Lerp(_currentTiltAngle.x,_movement.x * maxRollAngle,Time.deltaTime * responsiveness);// 应用欧拉角旋转(保持当前偏航角)transform.localRotation = Quaternion.Euler(_currentTiltAngle.y,transform.localEulerAngles.y,-_currentTiltAngle.x);}#endregion#region 环境检测系统[Header("地面检测设置")]public LayerMask groundLayer;    // 地面碰撞层public float groundCheckDistance = 5f;  // 检测距离[Tooltip("是否处于地面状态")]public bool isGround;            // 地面状态标识private RaycastHit _hit;         // 射线检测结果/// <summary>/// 地面接触检测(向下发射射线)/// </summary>void HandleGroundCheck(){isGround = Physics.Raycast(transform.position + new Vector3(0,1,1),transform.TransformDirection(Vector3.down),out _hit,groundCheckDistance,groundLayer);}// 编辑器可视化辅助void OnDrawGizmosSelected(){Gizmos.color = Color.red;Gizmos.DrawLine(transform.position + new Vector3(0,1,1),transform.position + new Vector3(0,1,1) + transform.TransformDirection(Vector3.down) * groundCheckDistance);}#endregion#region 螺旋桨旋转效果[Header("螺旋桨")][SerializeField]private Transform propella;void PropellerRotation(){// 螺旋桨旋转效果(转速与油门正相关)propella.Rotate(Vector3.right * throttle * 1000f * Time.deltaTime);}#endregion#region UI显示[Header("UI显示")][SerializeField]private Text hud;/// <summary>/// 更新飞行数据HUD显示/// </summary>private void UpdateHUD(){hud.text = $"油门: {throttle * 100:F0}%\n" +$"空速: {rb.linearVelocity.magnitude * 3.6f:F0} km/h\n" +$"高度: {transform.position.y:F0} m";}#endregion#region 音效void PlaySound(){audioSource.volume = throttle * 0.01f;}#endregion
}

专栏推荐

地址
【unity游戏开发入门到精通——C#篇】
【unity游戏开发入门到精通——unity通用篇】
【unity游戏开发入门到精通——unity3D篇】
【unity游戏开发入门到精通——unity2D篇】
【unity实战】
【制作100个Unity游戏】
【推荐100个unity插件】
【实现100个unity特效】
【unity框架/工具集开发】
【unity游戏开发——模型篇】
【unity游戏开发——InputSystem】
【unity游戏开发——Animator动画】
【unity游戏开发——UGUI】
【unity游戏开发——联网篇】
【unity游戏开发——优化篇】
【unity游戏开发——shader篇】
【unity游戏开发——编辑器扩展】
【unity游戏开发——热更新】
【unity游戏开发——网络】

完结

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果学习过程中遇到任何问题,也欢迎你评论私信找我。

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!
在这里插入图片描述

http://www.dtcms.com/a/321229.html

相关文章:

  • BUG调试案例十七:ENC424J600以太网掉线问题案例
  • uniapp瀑布流最简单的实现方法
  • SonarQube 扫描多个微服务模块
  • 【51单片机2个按键控制流水灯转向】2022-10-25
  • 移动端开发中类似腾讯Bugly的产品推荐与比较-5款APP异常最终产品推荐-卓伊凡|bigniu
  • springBoot集成minio并实现文件的上传下载
  • 华为网路设备学习-28(BGP协议 三)路由策略
  • 怎么实现对三菱PLC的远程调试和PLC远程维护?
  • 【世纪龙科技】数智重构车身实训-汽车车身测量虚拟实训软件
  • 矩阵中的最长递增路径-记忆化搜索
  • 【ESP32-menuconfig(1) -- Build Type及Bootloader config】
  • Vue 项目安全设置方案:XSS/CSRF 防护指南
  • 浅谈:如何复现修复Bug?
  • OpenCV 3 终极指南:创建炫酷自定义窗口与图像显示的艺术
  • 【代码随想录day 14】 力扣 111.二叉树的最小深度
  • Cesium 无人机视角飞行漫游,截屏
  • RabbitMQ详情介绍—七种工作模式
  • springmvc4+hibernate4整合框架的搭建
  • 库函数版独立按键用位运算方式实现(STC8)
  • Array Description(Dynamic programming)
  • 【网络编程】IO多路转接——epoll
  • Java文件读写(IO、NIO)
  • 第39周——训练自己的数据集
  • 汇编语言和高级语言的差异
  • BGP综合实验练习作业
  • Fabarta个人专属智能体:三维搜索链+动态大纲重构教材开发范式
  • Omron(欧姆龙)SysmacStudio软件下载,定期更新(最新更新到1.63升级包)
  • npm run 常见脚本
  • BGP协议笔记
  • 【新启航】航空飞机起落架深孔型腔的内轮廓测量方法探究 - 激光频率梳 3D 轮廓检测