本篇博客对直升机的飞行状态和攻击进行了简单的模拟,但是如果对仿真度没有太高的要求,这已经完全够用了。

对于旋转方式有困惑的可以参考https://blog.csdn.net/xdedzl/article/details/81488894

1.简易状态机基类

using UnityEngine;
using System.Collections;public class FSM : MonoBehaviour
{protected virtual void Initialize() {}protected virtual void FSMUpdate() {}protected virtual void FSMFixedUpdate() {}//Use this for initializationvoid Start(){Initialize();}// Update is called once per framevoid Update () {FSMUpdate();    }void FixedUpdate(){FSMFixedUpdate();}
}

2.直升机状态类

这个类里设置了三个外部调用接口,分别是StartAttack,SetTargetPos,SetEnemy,大家可以根据需要自行控制

​
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;/// <summary>
/// 直升机状态
/// </summary>
public enum HState
{Flying,  // 飞行Up,      // 上升Down,    // 下降Halt,    // 停止Hover,   // 悬停Aim,     // 瞄准
}public class Helicopter : FSM
{/// <summary>/// 攻击目标/// </summary>public Transform enemy;/// <summary>/// 移动目标点/// </summary>protected Vector3 targetPos;/// <summary>/// 攻击时间间隔/// </summary>protected float shootRate;/// <summary>/// 主旋翼/// </summary>public Transform mainRotor;/// <summary>/// 尾旋翼/// </summary>public Transform tailRotor;/// <summary>/// 发射器组/// </summary>public Transform[] launchs;/// <summary>/// 导弹/// </summary>public GameObject missile;/// <summary>/// 火箭弹/// </summary>public GameObject rocketSheel;/// <summary>/// 主旋翼旋转速度/// </summary>private float mainRatorSpeed;/// <summary>/// 尾翼旋转速度/// </summary>private float tailRatorSpeed;/// <summary>/// 最大俯仰角/// </summary>private float maxPitchAngle = 10;/// <summary>/// 最大横滚角/// </summary>private float maxRollAngle = 30;/// <summary>/// 最大升降速度/// </summary>private float maxLiftSpeed = 15;/// <summary>/// 最大移动速度/// </summary>private float maxMoveSpeed;/// <summary>/// 当前移动速度/// </summary>private float currentMoveSpeed;/// <summary>/// 旋转速度/// </summary>private float rotateSpeed = 1;/// <summary>/// 旋翼声音/// </summary>private AudioSource ratorSound;/// <summary>/// 移动后是否着陆/// </summary>private bool isLanding = false;/// <summary>///  是否已瞄准/// </summary>private bool isAim = false;public bool IsAim { get { return isAim; } }/// <summary>/// 武器种类/// </summary>private bool isMissile = false;/// <summary>/// 携弹量/// </summary>[SerializeField]private float weaponNumber = 8;/// <summary>/// 直升机当前状态/// </summary>private HState currentFlyState = HState.Halt;protected override void Initialize(){targetPos = transform.position + transform.forward * 0.1f;ratorSound = gameObject.GetComponent<AudioSource>();}protected override void FSMFixedUpdate(){RotateRotor();SwitchMove();}/// <summary>/// 旋翼旋转/// </summary>private void RotateRotor(){if (currentFlyState != HState.Halt){mainRatorSpeed = Mathf.Lerp(mainRatorSpeed, 15, Time.deltaTime);tailRatorSpeed = Mathf.Lerp(tailRatorSpeed, 20, Time.deltaTime);}else{mainRatorSpeed = Mathf.Lerp(mainRatorSpeed, 0, Time.deltaTime);tailRatorSpeed = Mathf.Lerp(tailRatorSpeed, 0, Time.deltaTime);}mainRotor.Rotate(0, mainRatorSpeed, 0);tailRotor.Rotate(tailRatorSpeed, 0, 0);}/// <summary>/// 选择飞行状态/// </summary>private void SwitchMove(){switch (currentFlyState){case HState.Flying:FlyingState();break;case HState.Up:UpState();break;case HState.Down:DownState();break;case HState.Hover:HoverState();break;case HState.Halt:break;case HState.Aim:AimState();break;default:break;}}/// <summary>/// 飞行状态的移动/// </summary>private void FlyingState(){YawRotate(targetPos, maxRollAngle); // 偏航float y = (targetPos - transform.position).normalized.y; // 获取y轴移动方向currentMoveSpeed = Mathf.Lerp(currentMoveSpeed, maxMoveSpeed, Time.deltaTime);transform.Translate(new Vector3(transform.forward.x, y, transform.forward.z) * currentMoveSpeed * Time.deltaTime, Space.World); // x,z轴方向用直升机自身方向PitchRotate(maxPitchAngle);   // 俯仰 飞行状态必俯仰// 抵达目标点后更改状态if (Vector3.Distance(transform.position, targetPos) < 5){currentMoveSpeed = 0;if (isLanding){currentFlyState = HState.Down;}else{currentFlyState = HState.Hover;}}}/// <summary>/// 悬停状态/// </summary>private void HoverState(){PitchRotate(0);RollRotate(0);}/// <summary>/// 降落状态/// </summary>private void DownState(){PitchRotate(0);  // 俯仰修正RollRotate(0);   // 横滚修正float height = transform.position.y - Terrain.activeTerrain.SampleHeight(transform.position);if (height < 0.1){ratorSound.Stop();currentFlyState = HState.Halt;return;}transform.Translate(Vector3.down * Time.deltaTime * Mathf.Lerp(Mathf.Min(height, maxLiftSpeed), maxLiftSpeed, Time.deltaTime));// 起飞速度以离地高度与飞行速度做插值// 控制旋翼声音ratorSound.volume = height / 10;}/// <summary>/// 起飞状态/// </summary>private void UpState(){float height = transform.position.y - Terrain.activeTerrain.SampleHeight(transform.position);if (height > 10){currentFlyState = HState.Flying;return;}YawRotate(targetPos, maxRollAngle);transform.Translate(Vector3.up * Time.deltaTime * Mathf.Lerp(height, maxLiftSpeed, Time.deltaTime));// 起飞速度以离地高度与飞行速度做插值if (!ratorSound.isPlaying){ratorSound.Play();}// 控制旋翼声音ratorSound.volume = height / 10;}/// <summary>/// 攻击状态/// </summary>private void AimState(){// 俯仰和偏航到指定角度Vector3 dir = enemy.position - (launchs[0].position + launchs[1].position) / 2;Quaternion rotation = Quaternion.LookRotation(dir);transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime);if (Vector3.Angle(dir, transform.forward) < 0.2){isAim = true;}else{isAim = false;}}/// <summary>/// 偏航 机身旋转/// </summary>private void YawRotate(Vector3 _targetPos, float rollAngle){float height = transform.position.y - Terrain.activeTerrain.SampleHeight(transform.position); // 获取当前物体相对地面高度if (height < 5){return;}Vector3 dir = _targetPos - transform.position;Quaternion targetRotation = Quaternion.LookRotation(dir);float angle = transform.eulerAngles.y - targetRotation.eulerAngles.y;if (angle < 0) angle += 360;if (angle > rotateSpeed && angle < 180){transform.Rotate(0f, -rotateSpeed, 0f, Space.World);RollRotate(rollAngle);}else if (angle < 360 - rotateSpeed && angle > 180){transform.Rotate(0f, rotateSpeed, 0f, Space.World);RollRotate(-rollAngle);}else{// 偏航完成if (currentFlyState == HState.Flying){RollRotate(0);}}}/// <summary>/// 横滚 左倾右倾/// </summary>/// <param name="target_z">横滚目标角度</param>private void RollRotate(float target_z){Vector3 currentEuler = transform.eulerAngles;Quaternion from = Quaternion.Euler(transform.eulerAngles);Quaternion to = Quaternion.Euler(new Vector3(currentEuler.x, currentEuler.y, target_z));transform.rotation = Quaternion.Lerp(from, to, Time.deltaTime);}/// <summary>/// 俯仰 前倾/// </summary>/// <param name="target_x">俯仰目标角度</param>private void PitchRotate(float target_x){Vector3 currentEuler = transform.eulerAngles;Quaternion from = Quaternion.Euler(transform.eulerAngles);Quaternion to = Quaternion.Euler(new Vector3(target_x, currentEuler.y, currentEuler.z));transform.rotation = Quaternion.Lerp(from, to, Time.deltaTime);}/// <summary>/// 初始化火力/// </summary>/// <param name="_launch">发射架</param>/// <param name="_target">打击目标</param>/// <param name="_Missile">导弹预制</param>/// <param name="_velocity">导弹速度</param>private void InitFirePower(Transform _launch, float _velocity = 400f){int index;if (isMissile){//实例化导弹实体,项目中要用对象池改写index = Random.Range(3, 4);GameObject _missile = Instantiate(missile, launchs[index].position, _launch.rotation);//实例化出来的导弹上挂导弹飞行的代码}else{//实例化火箭弹,项目中要用对象池改写index = Random.Range(0, 2);GameObject _rocketSheel = Instantiate(rocketSheel, launchs[index].position, _launch.rotation);//实例化出来的火箭弹挂火箭弹飞行的代码}launchs[index].Find("FireEffect").GetComponent<ParticleSystem>().Play();launchs[index].GetComponent<AudioSource>().Play();}/// <summary>/// 攻击 startAttack为外部调用接口/// </summary>private IEnumerator Attack(float delay = 0.1f){yield return new WaitForSeconds(delay);if (launchs.Length > 0){for (int i = 0; i < weaponNumber; i++){InitFirePower(launchs[0]);yield return new WaitForSeconds(0.2f);}}}public void StartAttack(){StartCoroutine(Attack());}/// <summary>/// 设置目标点/// </summary>/// <param name="_pos"></param>/// <param name="_speed"></param>/// <param name="_isLanding"></param>public void SetTargetPos(Vector3 _pos, float _speed, bool _isLanding){targetPos = _pos;maxMoveSpeed = _speed;isLanding = _isLanding;isAim = false;switch (currentFlyState){case HState.Down:case HState.Halt:currentFlyState = HState.Up;break;case HState.Hover:case HState.Aim:currentFlyState = HState.Flying;break;default:break;}}/// <summary>/// 设置攻击目标/// </summary>/// <param name="_enemy"></param>/// <param name="isMissile">武器是否是导弹</param>public void SetEnemy(Transform _enemy, bool _isMissile = true){if (launchs.Length <= 0){return;}enemy = _enemy;isMissile = _isMissile;if (currentFlyState == HState.Hover || currentFlyState == HState.Flying){currentFlyState = HState.Aim;}}
}

unity直升机飞行模拟相关推荐

  1. 基于unity的飞行模拟设计

    使用unity开发游戏真是非常方便.研究飞行模拟也有一段时日,尝试过物理和数学模拟.从效果上来看,物理模拟较为真实一点.但是操作不好.数学模拟的话,虽然牺牲了飞行效果,操控是非常方便的. 所谓的数学模 ...

  2. Unity游戏开发文档(1):飞行模拟

    前言     本篇的代码是基于Unity3D 系列课程 "Create with Code" 第一章 "Player Control" 改进而来 目录 背景 设 ...

  3. unity飞行模拟游戏源码,支持安卓+IOS双端 unity2019 C#语言开发

    unity飞行模拟游戏源码,支持安卓+IOS双端 unity2019 C#语言开发.完整的源码可直接运营.拿来学习研究和二次开发都很不错. 源码下载 unity2019飞行模拟游戏源码C#语言开发-U ...

  4. 基于知识图谱的直升机飞行指挥模型研究

    基于知识图谱的直升机飞行指挥模型研究 人工智能技术与咨询 昨天 本文来自<无线电工程>,作者齐小谦 关注微信公众号:人工智能技术与咨询.了解更多咨询! 摘 要: 针对当前直升机飞行指挥效率 ...

  5. 开发Unity3D空战类插件 战机飞行模拟模板

    Fighter Flight Template是本人开发的一款飞行模拟游戏模板,使用此模板可以帮助您轻松创建您自己的战机游戏 游戏控制 模板特点 战机的飞行系统是根据现代战机的空气动力学所设计的. 战 ...

  6. 开发Unity3D空战类插件 战机飞行模拟模板Pro版本

    Fighter Flight Template Pro是本人开发的一款飞行模拟游戏模板,使用此模板可以帮助您轻松创建您自己的战机游戏 游戏控制 模板特点 战机的飞行系统是根据现代战机的空气动力学所设计 ...

  7. 倾转旋翼飞行模拟(基于X-planeXV-15)

    前言:       和传统一样,受限于固定翼的起降需求和直升机的航程与速度限制,诞生了接触一下倾转旋翼的想法.但是我一没有科研需求,二没有项目支撑,于是决定从X-plane当中做出一些尝试,体验一下. ...

  8. 介绍简易制作飞行模拟游戏的方法(转)

    介绍简易制作飞行模拟游戏的方法(转)[@more@] 对许多网友而言,玩游戏是件令人愉快的事情,但是能因此而想到要去亲手制作一个游戏-----甚至是大型游戏的朋友可能就不是很多了,其中原因,说来也简单 ...

  9. 《微软飞行模拟》用AI还原全球15亿建筑,玩家发现bug:白金汉宫变成写字楼

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 全球最大的仿真游戏<微软模拟飞行2020>本周正式上线.这款游戏还原了全球200万个城镇.15亿座建筑物和3.7万个机场,让玩 ...

最新文章

  1. uml图中的各种箭头_设计模式学习笔记(二):UML与面向对象设计原则
  2. getaway网关转发去前缀_为什么微服务一定要有网关?
  3. Javascript中函数声明与函数表达式的不同
  4. apicloud入门学习笔记1:简单介绍
  5. CIO:权大、钱多、但难干 | 凌云时刻
  6. 为什么我们应该像盖房子那样写程序?
  7. Numpy学习---Task03---数组的操作
  8. 2022面试必刷461道大厂架构面试真题汇总+面经+简历模板
  9. Java游戏吉他英雄_《吉他英雄》全系列十作美版下载
  10. (14)树莓派B+使用L298N驱动控制四驱车并实现一个简单的web控制端
  11. 在树莓派上安装Ubuntu
  12. 正则表达式切掉log日志前面不需要的内容
  13. 黑客必用神器,网络抓包工具
  14. 高等数学二从零开始学习的总结笔记(持续更新)
  15. 插入k宝显示连接农行服务器失败,农行k宝插到win10电脑上没反应无法转账怎么办...
  16. Flex/FlashBuilder4.5破解
  17. 大学生影视主题网页制作 HTML+CSS+JavaScript (你好,李焕英 5页)
  18. 美女MVP教你轻松学习Excel VBA-方洁影-专题视频课程
  19. RoseHA配合DB2部署时,db2nodes.cfg问题
  20. ofdm中IFFT matlab,OFDM中IFFT后得到的数据应该怎样处理?

热门文章

  1. 解决Linux环境下重启后Java环境变量失效
  2. 轻量级分布式 RPC 框架DIY(转)
  3. [译] superagent中文使用文档
  4. 拆书帮第14期训练营——作业六:第一周复盘
  5. s19文件编辑_19个令人印象深刻的在线图像编辑器
  6. 一个男人的“变态”婚姻价值观
  7. windows所有版本列表_用Windows电脑训练深度学习模型?超详细配置教程来了
  8. 荣耀平板V6怎么样?设计专业学生来解答
  9. 一个比较漂亮的计算器
  10. 百度智能云联合发布《雄安新区2022年大数据研究报告》