李哲 发表于 2024-5-16 17:49:41

UE5 DIY飞行模拟器教程

如何用最先进的飞行动力学和全球数据集创建飞行模拟器上下文:
https://unrealengine.com/en-US/blog/antoinette-project-tools-to-create-the-next-generation-of-flight-simulators


介绍随着《Antoinette Project》的出版,我们想说明组装各种建筑模块并创建飞行模拟器的草图是多么简单和快速。由于虚幻商城资产的一些隐私要求,这个项目不能资源公开共享,但目前的教程将使您能够根据自己的意愿重新创建它。本文并不是针对初学者的详细分步教程,而是一个关于使用流程的通用指南。我们将指出各种外部参考资料,帮助您更多地了解某些概念或更深入地了解如何实现。您可以按照本教程中的解释创建自己的飞行模拟器应用程序,或者从托管在JSBSim GitHub存储库上的UE参考应用程序开始。后者将允许您创建个性化飞行模拟器。我们建议在构建自己的飞行模拟器之前完整查阅我们提供的教程内容。这样做将帮助您确定是应该从头开始还是使用JSBSim参考应用程序。环境内容创建地形圆形和世界尺度的环境全尺寸飞行模拟器有许多特定的要求,其中包括长距离飞行和高海拔飞行。在这些条件下,小规模和平坦的环境并不适合这项工作。你需要模拟特定的效果,比如地面地平线在视线水平以下,由于地球曲率,在高海拔地区也会变得可见。此外,如果你的环境是使用投影坐标系来设计的,那么实际的真实距离可能会因为椭球体的投影而失真。如果这对于小行程是可以接受的,那么对于较长的行程就行不通了。使用圆形环境一直是飞行模拟游戏的推荐方法,如此大型环境的另一个主要问题是坐标的精度水平。地球的半径是6378137米。在这个数量级上,单精度(32位)浮点编码标准的精度粒度为50cm。对任何坐标使用这些值都会导致精度差和大量抖动,这是不可接受的!有不同的技术可以解决这个问题,最主要的是原点重置,但它们会带来性能上的缺点,比如我们不希望在模拟中出现的故障。这就是为什么UE5的大世界坐标系统现在基于64位(又名双精度),这保证了在太阳系尺度上的高精度。‍‍‍‍‍此功能是UE5的核心。为了充分利用这个新功能,你必须在世界设置中启用“启用大型世界”选项。

在世界设置中启用大型世界
地理参考和坐标系统在圆形环境下,传统的Z-up笛卡尔坐标系就不适用了。一个人必须选择一个以地球为中心的参考系(又名ECEF),以地球中心为原点,或在特定位置的切线参考系。一旦固定,这个参照系将在模拟执行期间保持不变。最重要的是,地球上的位置通常用纬度、经度和海拔来表示,这是一个极坐标系,需要转换成笛卡尔坐标系。为了简化这些计算,Epic开发了一个地理参考插件,可以在所有这些参考之间转换地理空间坐标。它不仅可以帮助您在地球上定位,而且还被JSBSim运动组件(见下文)在幕后使用,该组件在ECEF坐标系中进行模拟。原始项目设置
从Game/BlankTemplate中启动一个新项目
一定要添加对c++的支持,但不需要Starter内容。项目以默认的横屏打开 你可以从这里开始,但今天我们不使用它。
在继续之前,先启用一些插件:
地理参考插件太阳位置计算器然后重新启动编辑器
创建一个新的Empty Level,不支持Open World。
确保在你的世界设置中启用大世界在关卡中放置一个地理参考系统角色。
在地球上选择一个合适的原点,在那里你想要你的应用程序开始(例如:机场),并设置相应的属性。这里我在蒙特利尔(YUL)机场取了一个点,就在跑道开始的地方。

在关卡中丢一个SunSky actor‍‍
这个actor包含了一个真实天空系统所需的所有组件。阳光的物理强度已经设置为它的真实值,所以不要忘记在你的项目设置中“扩展自动曝光的默认亮度范围”。确保Sky Atmosphere组件使用与你选择的地理参考模式一致的Transform模式。(对于切线帧,行星顶部位于绝对世界原点,对于ECEF帧,行星中心位于组件转换)。默认情况下,我们是在正切帧中,所以这里没什么可做的。稍后我们将为这个Actor定义适当的其他设置
如果你想了解更多关于设置一个不错的氛围照明,我们做了一个内部虚幻网络研讨会,这些步骤更详细地解释。
保存你的关卡,并将其设置为你的项目启动关卡。



从Game/BlankTemplate中启动一个新项目



设置正确的georeference设置


确保扩展默认亮度范围,否则你的天空将是白色的!
地形数据集现在我们有了一个空白的环境,让我们带来一些地形。对于这样大规模的环境,我们将依靠流技术。在虚幻引擎生态系统中有不同的解决方案。它们列在Project Antoinette的白皮书中为了便于说明,我将使用来自ESRI和Cesium的两个免费插件。两者都提供了详细的使用说明,所以我将参考它们各自的文档。选项1-虚幻引擎的ESRIArcGIS地图SDK。在撰写本教程时,该插件处于预发布阶段。我使用的是2022年4月的0.4.0版本,您可以在ESRI开发者网站上获得。ESRI网站上有详细说明:要使用这个预发布版,必须在UE项目根目录下创建一个“Plugins”子文件夹,并将ESRI插件放在那里。将其复制到那里后,需要重新生成VisualStudio项目文件(右键单击.uproject文件),并重新构建解决方案。(最终版本将不需要这些额外的步骤)。遵循说明时,不要忘记将原始引用设置为您之前选择的相同位置,以输入ESRI API Key,并最终输入其他数据层。(例如:MontrealBuildings)。


一定要输入和之前一样的地理参考



世界图像就足够了,但可以随意添加额外的数据层……


来自ESRI的蒙特利尔市区
选项2-Cesium 虚幻引擎。这个插件可以在Marketplace上找到,cesium在他们的网站上写了很多如何使用它的教程
我们在环境中添加了WorldTerrain+BingMapsAerialImagery+OSMBuildings。再次强调,将Cesium Georeference Actor的Origin Placement设置为UE georeference插件完全相同的值是非常重要的。
你可以选择Cesium天空或选择另一个,但要注意不要同时拥有多个天空系统!




选择您选择的Cesium层



确保输入与之前相同的地理参考


蒙特利尔机场,来自cesium世界数据集模型
当地详细的机场插图‍‍‍
一个人可以决定像在机场一样直接在地形上起飞或降落,但大多数时候我们需要一条正确的跑道。通常,我们会在高清机场使用当地的详细插图。这些机场被放置在世界各地的不同位置。对于这个项目,我只是制作了一个简单的带有基本标记的跑道,并将其放置在持久关卡的原点周围。在绘制标记时,我使用Z=0作为跑道的几何形状。这种方法通常会导致标记闪烁,但如果你使用DeferredDecalDomain将标记放在单独的材料中,你就永远不会有这个问题!对于这些标记的含义感到好奇的人,可以看看FAA的这个页面将静态网格添加到关卡中,并精确定位。底层地形可能会穿过它。在这种情况下,需要一个切口。当使用cesium时,很容易使用地图多边形来剪切插入区域。

使用外部DCC工具制作的简易跑道‍



如果下面的地形不是平坦的,可能会有一些闪烁。


一个Cutout可以很容易地解决这个问题飞机现在我们有了一个基本的环境,我们需要一架飞机来驾驶。根据你的案例,你可能想要飞机的内部或外部,或者你可能想要两者兼而有之。如果你的团队中有美工,那你就很幸运了。就我而言,我只能在Marketplace上找。我挑选了这两项资产:
商用飞机。
这个模型很有趣,因为它是一个蒙皮的网格,它有我们需要的所有动画:副翼,电梯,方向舵,还有起落架和涡轮机。请注意,在这个项目的上下文中,这个资产已经为所有人自由设置!
客机(https://www.unrealengine.com/marketplace/en-US/product/airliner)。
如果你想看内景‍

稍后我们将看到如何将这两个模型结合成一个完整的蓝图。但在实际用例中,艺术家会比我做得更好!


来自市场的商用飞机


飞行动力学与场景天气基本天气和太阳在这个演示中,我只想使用引擎中可用的功能。人们可以使用其他人做的更高级的实现,比如Ultra DynamicSky,但现在,我们将使用Sunskyactor附带的太阳位置计算器插件。这个插件在架构模板中使用,包含一个SunSkyactor,它包含不同的组件:一个定向光(太阳),一个天窗和一个天空大气。这个Actor蓝图使你能够根据你当前的位置和时间在天空中定位太阳,但它还不包含任何云。别担心,我们会添加我们自己的云。选择在前面步骤中添加到关卡中的SunSkyactor,并进行一些调整:
位置和方向
输入与之前相同的gereference点,加上相应的时区(相对于GMT时间)检查Compass与地形几何的对齐情况。使用ESRI或Cesium数据集,北方向是朝向-Y的,所以我们需要使用-90向北偏移来正确对齐。
一天中的时间
选择你想要的任何日期和时间,但是选择一个黄金时间(日落前的最后一个小时和日出后的第一个小时)会给你带来极好的效果。由于我们处于球形地球模式,无论你在地球上的位置如何,太阳的方向都是正确的。只要确保你在长途飞行中正确地更新了一天中的时间。
光照和阴影范围
选择定向光组件,并将动态阴影距离提高到更适合大型世界的距离。(2-3km,所以200000)。使用UE5虚拟阴影地图,对性能的影响很小。我们稍后会看到如何调整曝光…   

只需向这个角色添加一个体积云组件。我觉得体积云材质的默认值给了太光滑的云。
我通常创建一个新的材质实例,并使用下面的值设置它。



新的云材质实例有更多的“嘈杂”设置‍



云材料-之前


云材料-之后AircraftwithCo-Simulation建造飞机Pawn蓝图‍这个飞机actor是我们计划控制的。他将收到我们的输入,并相应地在地球上移动。因此,它是一个Pawn。
创建一个新的BP类Pawn,命名为bp_客机。
它需要有一个可视化的表示,以便让我们组装我们从市场下载的不同模型。
提示:当你在最终项目中添加市场道具时,它们通常会附带一些你并不关心的资产(例如:展示关卡,集合中的其他道具)。根据你的包装设置,你最终可能会得到一个你不需要的额外的应用程序大小。
要处理这个问题,推荐的方法是创建一个空的临时项目将项目添加到该项目中只挑选你需要的,并使用“迁移资产”功能将它们和唯一需要的引用移动到你的最终项目中。在内容浏览器中安排它们的位置,并在完成后修复文件夹中的重定向。
所以,一旦你迁移了项目中所有需要的资源:
添加一个骨架网格组件,并将其设置为外部网格。添加静态网格组件并将其设置为内部网格。将其放置在视口中。如果你的资源包含多个网格,将它们分组在Scene Component下。
如果你不需要同时显示内部和外部,你可以截取一个模式选择,并相应地隐藏部分。这将为你节省一些几何体来渲染。




飞机蓝图的外部是骨架网格,内部是一组静态网格

飞机外



飞机驾驶舱


现在,让我们从本教程的重点部分开始吧!用飞行动力学模型进行联合仿真。模拟飞机的行为比仅仅应用前进速度和改变用户输入的偏航俯仰滚转角度要复杂得多。许多力都适用于模型:重力、升力、阻力、风、湍流、副翼上的力等等。其中一些力取决于飞机本身,可以随时间变化,比如质心,质心的位置会随着油箱填充百分比的变化而变化。还有一些则取决于环境本身。比如电梯,取决于速度、空气密度和温度,当然还有风。即使是一个简单的螺旋桨,也能给飞机局部增加扭矩。虽然所有这些单独的因素都可以表示为外部扭矩和力,并由混沌物理引擎解决,但依靠现有的和经过验证的飞行动力学模型更有效。为此,我们决定使用JSBSim飞行动力学模型JSBSim是一个开源飞行动力学模型(FDM),可以在许多操作系统下编译和运行。FDM本质上是一个物理/数学模型,它定义了飞机、火箭等在各种控制机制和自然力作用下的运动。目前使用JSBSim的最突出的例子是FlightGear,Outerra,BoozSimulator和OpenEagles。JSBSim还用于驱动意大利那不勒斯大学和德国亚琛工业大学飞行系统动力学研究所和航空航天研究所的基于运动的研究模拟器。它通过基于xml的文本文件格式附带了一个完全可配置的飞行控制系统,空气动力学,推进,起落架布置等,考虑到旋转地球对运动方程的影响(科里奥利和离心加速度建模),并且可以很容易地插入任何c++程序。这个开源的飞行动态API已经被集成到一个虚幻引擎插件中,我们在他们的官方GitHub上发布了这个插件。我们还添加了一个参考UE应用来给出这个集成的简单例子。如果你想了解更多关于这个模块的知识,我们建议你先看看这个简单的应用,从中学习,然后再深入学习,制作一个像这样更复杂的应用。为了能够在您自己的应用程序中使用JSBSim,您必须
克隆或分叉计算机上的JSBSim存储库通过构建JSBSimForUnreal,对JSBSim库进行特殊构建解决方案。
它将构建JSBSim作为虚幻的静态库,并将它们放置在JSBSim\UnrealEngine\插件\JSBSimFlightDynamicsModel插件文件夹中。它还将复制这个插件的资源文件夹中的所有JSBSim飞机/引擎定义,因此它是自包含的,可以使用。
如果不是从JSBSim UE Reference App开始,只需将编译后的JSBSimFlightDynamicsModel文件夹复制到项目插件文件夹中,然后按照下面的步骤操作。
这个插件基本上添加了一个新的“JSBSim运动”组件包装在飞行动态模型。在每一帧,你只需要负责输入飞机命令结构,运动组件将为你做剩下的工作,设置实际的飞机变换。您还可以访问飞机状态,并将其用于各种目的,例如动画运动部件或显示HUD。
将这个JSBSim移动组件添加到你的飞机蓝图中。输入Aircraft Model属性的名称
它必须存在于JSBSim库中——如果没有,请自己编写!它将加载相应的JSBSim模型,并在3D模型上显示一些参考点。
由于JSBSim是完全视觉无关的,你必须编辑“结构框架原点”属性,使其与你使用的3D模型几何形状相匹配。
至少让起落架正确匹配是很重要的。

注意:在此应用程序和UE Reference App的上下文中,从市场中获取的3D模型是777,这在JSBSim库中不可用。我们不得不使用FlightGear中可用的787-8模型,并做一些几何近似来匹配一些东西。当然,在真实飞行模拟项目的情况下,你会有3D和动态模型完美匹配。


编辑结构框架原点,让FDM模型匹配你的3D模型几何形状‍模型的属性预先填充了来自JSBSim模型的默认值。其中一些属性是可编辑的,比如tank的内容。编辑初始条件属性:
飞机:
地面开始:飞机在开始时被认为是静止的(从物理角度来看是睡眠的)。如果你想起飞,就检查一下。从放下装备开始:在地面开始的时候必须是true。以发动机运行开始:如果为true,发动机应该已经启动了,油门命令才会生效。如果为假,你就必须完成所有的启动程序,每个发动机的启动程序都是不同的。启动时的Flag Position:这是一个归一化值初始校准Air Speed:飞机在空中启动时的初始速度。
环境设置:
默认风力条件。
如果你不想使用JSBSim默认值(海平面温度/压力),你可以通过选中“Control FDM Atmosphere”复选框来覆盖这些设置。




通过JSBSimMovement属性定义飞机的初始条件

连接基本的用户输入要驾驶飞机,我们需要一些基本输入。这必须像在任何虚幻引擎应用中一样,使用输入系统来完成。一旦这些输入动作和轴被定义,我们将它们连接到飞机蓝图中适当的FlightCommand值。请注意,当您使用“在结构体中设置成员”设置值时,您必须将其重新应用到组件变量以更新它。执行的正确方法是:
获取对开始播放上的Commands结构体的引用,并将其存储为一个本地BP变量。使用“在结构体中设置成员”节点设置这个局部结构体的成员。
每次更改时,将其重新应用到JSBSim移动组件。




注意:仅用键盘控制飞机并不是一个好主意。将0/1值设置为坐标轴会使模型不稳定且不可预测。对于键盘控件,建议使用“incree command value”或“elime command value”来避免如此大的跳跃。驾驶飞机的最佳方式仍然是使用专用的模拟设备(见下文)。但如果你想在同一个应用中同时使用这两种设备呢?如果你想通过键增加/减少一个变量值,它将被来自模拟设备的轴值覆盖。在JSBSim的UE Reference App中,我们通过使用输入优先级函数解决了这个问题。



铰接部件制作动画根据仿真值制作骨架网格动画时,基本上有两种策略。
“pushing”:Actor蓝图将在开始播放时获得动画蓝图的引用,并将在每个tick上设置ABP变量。“pulling”:动画蓝图将在其Update animation事件中从actor蓝图中读取任何感兴趣的变量,然后将这些值转换为ABP变量,用于驱动Animgraph中的动画。

两者都有利有弊,但我个人更喜欢第二种,原因有二。
它允许对相同的BPActor具有不同的ABP。一个人可以从一个动画开始,或者只有几个动画,然后升级到更复杂的动画。如果不同的骨架网格有不同的索具(例如:不同的角度或BlendSpace),这是适应这种配置的ABP,而不是BPActor知道它。它允许BPActor的更多可重用性。

你可以在JSBSim UE Reference App中找到一个完整的动画系统。




部署&基础设施可视化界面简单的桌面屏幕显示,带有双摄像头设置这个简单的演示只针对桌面端。它可以很容易地通过OpenXR扩展到任何XR设备,甚至是一个复杂的多通道投影系统,如使用nDisplay的圆顶。如果你对虚幻引擎如何支持任何复杂的投影系统感到好奇,你可以阅读nDisplay白皮书在这里,我们将创建一个具有双摄像头配置的Pawn,可以通过“Tab”键进行切换。
创建两个摄像头组件
其中一个命名为“Pilot”,用于内部视图另一个被命名为“OrbitCamera”,用于外部视图。将这个添加到一个弹簧臂组件中。
在事件图中,将与Tab键关联的InputAction绑定到一个翻转/翻牌节点,并相应地激活/停用相机。
你可以用鼠标添加一个OrbitCamera行为



驾驶舱内飞行员摄像机


外部摄像头连接在弹簧臂上


控制曝光你可能已经注意到,使用SunSky actor,如果你在晚上设置时间,你可能无法获得黑暗或至少逼真的环境。这是因为默认情况下,引擎色调映射器会放大光线,这比你的眼睛能做到的要好得多。为了控制这一点,你需要将眼睛的适应限制在一个特定的水平上。
在场景中添加一个Post Process Volume启用它的“无限范围”标志。在曝光设置上:
检查MinEV输入一个接近13.5的值。这大致相当于眼睛的敏感度。

如果你愿意,也可以改变眼睛的适应速度



黄昏时限制曝光
触觉界面连接战斗控制,轭和油门,Hotas专用的飞行模拟设备往往是非常复杂的设备,有很多按钮或轴。它们不会被操作系统识别为操纵杆或gamepad。然而,虚幻引擎能够使用RawInput插件来支持它们。在这个演示中,我使用了这些设备:Alpha Flight Control-Yoke&SwitchPanel(Honeycomb)Bravo Throttle Quadrant (蜂窝)G Pro Flight Rudder Pedals(罗技)


原始输入插件最初是为了支持像赛车轮这样的设备而设计的,这些设备被系统视为单个设备。在我们的例子中,有三个不同的设备,每个都有一个特定的制造商和设备ID,都重定向到一个单一的玩家输入。但原始输入插件不能同时从几个设备读取。我们对它进行了一些编辑以支持这种特殊情况,这些更改无法在UE5.0版本中实现。幸运的是,他们已经提交了,并且会在5.1版本中出现。如果你需要这些更改,你可以在GitHub上获取最新版本的源代码,在ue5-main分支上。,并将其本地添加到你的项目中(你可以在这里找到插件)。
启用插件进入项目设置/插件/原始输入添加三个设备配置Alpha Flight Control-供应商ID=294B/产品ID=1900Bravo Throttle Quadrant -供应商ID=294B/产品ID=1901G Pro Flight Rudder Pedals-供应商ID=06A3/产品ID=0763对于每个设备,编辑Axis属性
为了帮助找出坐标轴,你可以运行Windows Game Controller实用程序,在启动菜单搜索中输入“Game Controllers”,然后运行“setup USB Games Controllers”将每个需要的轴转发到您选择的“Generic USB Controlleraxis#”值。可以编辑倒置和偏移值来重新映射轴的范围。注意,这个值在所有设备中必须是唯一的。建议有一个干净的和文档化的映射方案。
对所有需要的按钮做同样的操作,并将它们映射到“Generic USB Controller Button#”
输入完成后,在相应的映射中添加相应的“Generic USB Controller Axis#”和“Generic USB Controller Button#”输入…


3个设备的RawInput设置示例


在输入系统中使用“GenericUSBController轴#”和“GenericUSBController按钮#”

输入结语与观点

通过在虚幻引擎5平台上组装一组各种组件,我们成功地快速创建了一个具有高质量飞行动力学和出色渲染质量的基本飞行模拟器。


video: https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_3356094157962084353一个DIY飞行模拟器教程
当然,这只是一个简单的项目来说明主要需要的步骤。在更现实的用例中,应该创建更多的飞机,模拟它们的内部系统,并使用像这些这样的2D/3D UMG小部件来显示飞行仪表。或者可能做一个VR或nDisplay版本。世界是你的!在JSBSim GitHub存储库上发布的参考应用程序,旨在刺激飞行模拟爱好者,业余爱好者或专业人士。我们希望它能给你带来许多其他的想法,也希望这个项目能随着你的贡献而不断发展。我希望你喜欢这个教程,就像我们创造它的乐趣一样!Epic模拟团队!

近期焦点虚幻引擎5.4现已发布GDC 2024:来自State of Unreal的重大新闻欢迎来到全新的虚幻引擎网站
我们将在四月下旬更新虚幻引擎、Twinmotion和RealityCapture的定价祝贺《War is Over》 荣膺第96届奥斯卡最佳动画短片奖透过MEGA聊虚幻- 理想汽车设计团队专访UE动画导入标准流程!

扫描下方二维码,关注后点击菜单栏按钮“更多内容”并选择“联系我们”获得更多虚幻引擎的授权合作方式和技术支持。

长按屏幕选择“识别二维码”关注虚幻引擎“虚幻引擎”微信公众账号是Epic Games旗下Unreal Engine的中文官方微信频道,在这里我们与大家一起分享关于虚幻引擎的开发经验与最新活动。
页: [1]
查看完整版本: UE5 DIY飞行模拟器教程