KY-RTI分布仿真技术:第十三章 基于Unity的多语言三维态势仿真——以 Island Assault(夺岛突击)想定为例

KY-RTI在兼容DMSO RTI-NG1.3的基础上,原生支持C++、Java、Python、C#等多种程序设计语言,使同一联邦内可以同时发挥算力、人工智能决策与Unity三维显示等各自优势。本文介绍一个完整的多语言联合仿真示例Island Assault(夺岛突击),重点说明C#仿真成员如何与Unity(团结引擎)项目联合,将联邦对象属性与交互事件实时映射为三维态势画面。

1 3.1 基于 KY-RTI实现Unity与AI联合仿真

传统DMSO RTI以C++为主。现代仿真系统往往同时需要:高性能连续系统仿真、可维护的业务规则、快速迭代的人工智能算法,以及沉浸式三维态势显示。若各子系统采用不同语言却缺乏统一的RTI接口,则不得不额外开发私有中间件,增加接口不一致与联调成本。

KY-RTI的多语言能力可以在同一HLA联邦内支持新一代仿真系统。Python生态成熟,便于实现规则智能体或接入大模型等AI能力;C#与Unity/团结引擎同属.NET语言栈,仿真成员代码可直接运行于图形引擎进程内,无需JNI或额外进程桥接。因此,构建"基于Unity并支持AI"的仿真系统,KY-RTI是较为合适的技术选择。

13. 1.1 多语言能力与典型分工

表1给出了KY-RTI常见编程语言在联合仿真中的典型定位,以及在Island Assault想定中的具体用法。

表1 基于KY-RTI多语言的想定分工

|------------|----------------|------------------|
| 程序设计语言 | 典型优势 | 在本想定中的职责 |
| C++ | 高性能数值计算与连续动力学 | 平台运动、开火命中与毁伤计算 |
| Java | 项目业务规则与条令逻辑 | 蓝方探测、岸导反舰与防空交战 |
| Python | 人工智能与快速迭代 | 红方指挥决策、导调裁决与剧情注入 |
| C# | 原生对接Unity/团结引擎 | 三维态势显示 |

13. 1.2 无tick运行方式对图形仿真成员的意义

KY-RTI支持在RTI.rid配置文件中关闭UsingTickSwitch,使仿真成员不必调用rti.tick()服务。该模式特别适合Unity一类由引擎主循环驱动渲染的程序,支持图形帧与HLA回调解耦,避免在Update中轮询tick,也降低主线程被RTI阻塞的风险。Island Assault全体仿真成员均采用该策略。

1 3. 2 . Island Assault想定概述

Island Assault仿真程序位于KY-RTI安装目录下的island-assault文件夹。联邦执行名称为IslandAssault,联邦对象模型(FOM)文件为bin目录下的island_assault.fed。

13. 2.1 作战剧情

想定背景为红方编队对蓝方岛屿进行夺控,完整流程约四分钟。阶段划分如下:

  1. 侦察阶段------无人机前出,查明雷达与岸导部署;
  2. 联合打击阶段------战斗机与驱逐舰压制雷达、岸导及防空阵地;
  3. 抢滩登陆阶段------登陆舰与两栖战车逼近控制点,推进占领进度;
  4. 终局裁决------占领全部岛屿则红方胜利;超时未能夺控,或登陆核心兵力被歼且占领不足,则蓝方胜利。导调仿真成员可在运行中注入增援、受损、海况等事件,胜负不定,红方或蓝方都有赢的机会,便于演示多仿真成员协同与对抗博弈。

13. 2.2 三维态势画面要素

三维Viewer运行后,场景中可见简易的三维动画:海面与岛屿、红方舰艇/飞机/两栖战车、蓝方雷达/岸导/防空/控制点,以及开火弹道、命中闪光与击毁效果;界面左上角同步显示作战阶段、剩余时间、占领百分比、比分、AI决策摘要与胜负结果。

1 3. 3 . 联邦构成:五个仿真成员

本联邦由五个仿真成员组成。建议先启动业务仿真成员,最后启动导调仿真成员(Referee在加入后约等待三秒再开局)。表2列出了各仿真成员的目录、程序设计语言与职责。

表2 Island Assault五个仿真成员

|--------|-----------------------|--------|----------------------------------|
| 序号 | 目录 | 语言 | 仿真成员职责 |
| 1 | 01-dynamics-cpp | C++ | 动力学/真值状态:发布红方Platform;运动、开火与毁伤计算 |
| 2 | 02-blue-doctrine-java | Java | 蓝方条令:发布岛上Facility;探测与岸导/防空交战 |
| 3 | 03-red-ai-python | Python | 红方AI:按阶段下达CommandOrder并播报决策 |
| 4 | 04-viewer-unity | C# | 三维态势:订购对象与交互,映射为Unity场景 |
| 5 | 05-referee-python | Python | 导调/裁判:阶段时钟、占领计算、剧情注入与胜负宣布 |

数据关系可概括为:Dynamics与BlueDoctrine分别发布平台与设施属性;RedAI向Dynamics发送指挥命令;Referee发布任务状态与控制点占领进度,并发送任务控制与胜负交互;Unity Viewer订购上述对象属性及FireWeapon、DamageReport、AiDecisionAnnounce等交互,完成三维呈现。Viewer为三维态势显示,不参与裁决,也不发布对象实例。

1 3. 4 . C#仿真成员与Unity 项目 的联合实现

在对外集成时,用户最关心C#仿真成员如何加入联邦,依赖哪些库,脚本如何组织,以及RTI回调线程如何与Unity主线程协作,最终把HLA数据变成可见的三维对象等。

如图1所示,在Tuanjie Hub 1.4.4的项目列表中可以看到IslandAssaultViewer,对应编辑器版本为1.9.3。

如图2所示,从图1中点击IslandAssaultViewer,则团结引擎1.9.3会加载三维态势项目 IslandAssaultViewer。

如图3所示,在Tuanjie编辑器1.9.3中,RtiViewer挂载Rti Federate Bootstrap,以仿真成员名 UnityViewer加入KY-RTI 联邦。

图1 用Tuanjie Hub打开本例三维工程

图2 团结引擎加载IslandAssaultViewer项目

图3 团结编辑器中的RtiViewer与Bootstrap组件

13. 4.1 项目 目录与脚本组织

表3给出了Viewer相关目录。UnityScripts目录保存脚本副本(IslandAssaultViewer\Assets\Scripts\的备份,这是Unity/团结项目真正编译、运行用的脚本);IslandAssaultViewer为实际的团结/Unity项目。

表3 Viewer项目目录

|------------|------------------------------------------|
| 内容 | 目录 说明 |
| Viewer总目录 | island-assault\04-viewer-unity\ |
| 脚本源码副本 | ...\UnityScripts\*.cs |
| Unity/团结项目 | ...\IslandAssaultViewer\ |
| 项目内编译脚本 | ...\Assets\Scripts\ |
| 托管插件目录 | ...\Assets\Plugins\ |
| 演示场景 | ...\Assets\Scenes\IslandAssault.scene |
| 编辑器版本 | 团结引擎1.9.3(对应Unity 2022.3系列构建) |

该目录下的ConsoleViewer为命令行的纯C#控制台态势程序,可在无图形环境下先验证仿真的正确性,然后再在其基础上开发Unity三维项目IslandAssaultViewer。

13. 4.2 依赖库

Unity项目通过Assets/Plugins引用KY-RTI安装目录lib下的依赖库。全体仿真成员在RTI.rid中将UsingTickSwitch设置为Off,Unity侧禁止调用rti.tick()。

13. 4.3 核心脚本职责

脚本命名空间为IslandAssault.UnityViewer。表4说明各脚本功能。

表4 Unity项目核心脚本职责

|----------------------------|-----------------------------------------------|
| 脚本文件 | 功能 |
| RtiFederateBootstrap.cs | 入口MonoBehaviour:加入联邦、订购、每帧同步场景、标签与相机、退出resign |
| UnityFederateAmbassador.cs | 继承FederateAmbassador,接收回调消息 |
| ViewerState.cs | 联邦快照(对象字典、任务字段、句柄缓存、Gate锁) |
| RtiValues.cs | 清洗C++属性串尾部NUL,并按不变区域性解析浮点数 |
| MarkerFactory.cs | 运行时拼装舰/机/车/阵地造型;MarkerVisual处理命中闪光与击毁外观 |
| BattlefieldEnvironment.cs | 生成海面、浅滩与岛屿 |
| BattleHud.cs | UI Text刷新阶段、时间、占领、比分、AI文案与胜负 |

场景接线要求如下:空物体(如RtiViewer)挂载RtiFederateBootstrap;Canvas下Text(Legacy)挂载BattleHud,并将Bootstrap引用拖入;保留Main Camera,可启用自动框场。可指定红/蓝Prefab;未指定时由MarkerFactory生成简易造型。

13. 4.4 加入联邦与 订购 策略

RtiFederateBootstrap在Start中调用JoinFederation:创建RTIambassador与UnityFederateAmbassador,尝试createFederationExecution(联邦已存在则忽略),再joinFederationExecution,默认仿真成员名为UnityViewer,随后CacheHandlesAndSubscribe完成句柄解析与订购。Viewer为只读仿真成员,不调用publishObjectClass、registerObjectInstance或sendInteraction。

表5列出了Viewer订购的主要对象类属性与交互类。

表5 Unity Viewer订购的对象类与交互类

|--------|--------------------------------|--------------------------|
| 类型 | 名称 | Viewer用途 |
| 对象类 | Platform | 红方平台位置、类型、生命值与状态 → 舰机标记 |
| 对象类 | Facility | 蓝方设施位置、类型、生命值与状态 → 阵地标记 |
| 对象类 | MissionState | 阶段、剩余时间、比分、胜负、AI决策 → HUD |
| 对象类 | ControlPoint | 占领进度 → HUD与控制点语义 |
| 交互类 | FireWeapon | 开火起止点 → 弹道与抛射体特效 |
| 交互类 | DamageReport | 命中与摧毁标志 → 闪光、击毁姿态 |
| 交互类 | AiDecisionAnnounce | 指挥播报 → HUD文案 |
| 交互类 | DeclareWinner / MissionControl | 胜负与任务阶段提示 |

如果晚加入仿真,则discoverObjectInstance之后对平台/设施调用requestObjectAttributeValueUpdate,主动拉取关键属性,避免仅发现实例名而长时间看不到坐标与类型。

13. 4.5 回调线程与Unity主线程解耦

在UsingTickSwitch Off模式下,FederateAmbassador回调线程与Unity主线程可采用lock锁进行同步。

13. 4.6 属性到三维对象的映射

属性反射进入ViewerState.Ent后,主线程SyncMarker完成可视化。坐标约定为:HLA以(x,y)为水平面、z为高度;Unity中取(x×worldScale, z×worldScale, y×worldScale)。默认worldScale=0.05,可将千米级战场收入同一Game视图。设施略抬高以免陷入岛面网格。击毁后冻结残骸位姿、飞机下沉,数秒后隐藏,且不参与相机包围盒计算,避免相机跟随活体编队时造成"击毁单位仍在飞行"的观感。中文标签采用OnGUI屏幕空间绘制,由MarkerFactory.ChineseLabel完成标识到中文名称的映射。

13. 4.7 开火与毁伤特效管线

收到FireWeapon与DamageReport回调消息后,由主线程PlayFx处理。开火优先使用交互参数中的起止坐标生成LineRenderer弹道与短时抛射体,红蓝双方使用不同色调以便区分;命中触发闪光与粒子,摧毁标志为真时切换击毁外观。命中率与毁伤数值由Dynamics与BlueDoctrine计算,C# Viewer只负责表现,不在Unity内重复计算交战逻辑。

13. 4.8 退出与联邦清理

在Unity中停止Play或销毁挂在 RtiViewer 上的RtiFederateBootstrap组件时调用ResignQuiet:在后台任务中执行resignFederationExecution和destroyFederationExecution。

1 3. 5 . 演示

下面按演示视频的播放时间介绍Island Assault完整联调过程。演示视频在线地址:https://live.csdn.net/v/536887 。视频前半段展示KY-RTI安装目录与各语言示例结构,随后启动RTIManager与五个仿真成员,并在Unity三维态势中完成侦察、打击、抢滩与终局裁决。表6给出主要时间节点与对应画面内容。

演示视频KY-RTI-Unity-CSharp

表6 演示视频时间轴(KY-RTI-Unity-CSharp)

|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 时间 | 演示 内容 |
| 0:00 | 资源管理器打开D盘,选中KY-RTI安装目录,开始介绍整体目录布局。 |
| 0:15 | 进入apps-cpp示例(如chat的Release目录),展示C++仿真成员可执行文件与RTI.rid。注意目录下的Makefile文件,在Linux下用户可以使用该文件编译程序;当前,Linux和Windows的目录结构几乎完全一致,除了C++库名不同外,几乎所有示例都适用于两个操作系统。 |
| 0:36 | 浏览apps-csharp/time-notick,展示C#仿真成员源码(HwFederateAmbassador.cs、TimeManagement.cs等)。 |
| 0:45 | 返回KY-RTI根目录,依次展示apps-java、apps-python3、apps-qt及island-assault等文件夹。 |
| 1:00 | 浏览apps-python3示例(如time-notick、checkpoint-save),checkpoint-save即为第12章介绍的HLA联邦保存与恢复示例。 |
| 1:36 | 进入island-assault\03-red-ai-python,展示红方AI仿真成员源码。 |
| 1:45 | 进入04-viewer-unity,展示ConsoleViewer、IslandAssaultViewer项目与UnityScripts目录;ConsoleViewer为命令行仿真代码(本示例未演示),IslandAssaultViewer为本示例演示的三维仿真代码。 |
| 2:00 | 打开UnityScripts,对照RtiFederateBootstrap、UnityFederateAmbassador、BattleHud等核心脚本。 |
| 2:12 | 进入D:\KY-RTI\bin,可见island_assault.fed、RTIManager.bat、KY-RTI可执行程序及configure.rti。这里提示了save目录下的savepoint1和savepoint2两个文件,是之前演示保存和恢复功能时生成的文件;还有Linux下的RTIManager.sh脚本文件。当前,Linux和Windows的目录结构几乎完全一致,除了C++库名不同外,几乎所有示例都适用于两个操作系统。 |
| 2:28 | 选中RTIManager.bat,准备启动KY-RTI管理控制台。 |
| 2:35 | 启动RTIManager。命令行界面显示了KY-RTI管理控制台的可用IP地址和端口号20000,并提示更多的信息可以参考rti_ips.txt文件,之后打开KY-RTI图形控制台。 |
| 2:45 | 控制台就绪,联邦成员列表为空;终端进入01-dynamics-cpp的Release目录准备启动动力学成员。 |
| 2:55 | 切换至团结引擎/Unity Hub,打开IslandAssaultViewer项目。 |
| 3:05 | 进入IslandAssault场景,Hierarchy中可见RtiViewer、Canvas等对象;Game视图尚为占位界面。 |
| 3:10 | 点击Play,团结引擎执行Domain Reload并进入运行态。 |
| 3:15 | Unity仿真成员加入成功,控制台日志显示UnityViewer已加入;HUD为idle,胜负pending。 |
| 3:25 | 启动dynamics.exe(C++),生成红方驱逐舰/登陆舰/战斗机/无人机/两栖战车等平台;RTIManager显示UnityViewer与Dynamics。 |
| 3:28 | 启动java BlueDoctrine(蓝方条令仿真成员);联邦成员增至3个。 |
| 3:30 | 启动python RedAI.py(红方AI仿真成员);终端提示Waiting for phases;成员增至4个。 |
| 3:35 | 在05-referee-python目录准备执行python Referee.py。 |
| 3:38 | 启动导调/裁判仿真成员Referee,等待约3秒后进入PHASE RECON。 |
| 3:50 | 切回Unity三维态势。作战阶段为recon,无人机前出侦察;可见蓝方雷达探测与防空/岸导开火特效。 |
| 4:12 | 进入联合打击阶段(strike),HUD显示AI优先压制雷达B-RADAR-1,红方舰艇对岛上设施开火。 |
| 4:48 | 进入抢滩登陆阶段(land),AI提示岛上火力点已清除,登陆舰与两栖战车逼近控制点。 |
| 5:36 | 对照Referee终端日志与RTIManager成员列表,可见导调注入事件(如登陆舰受损、航速下降)及持续交战记录。 |
| 6:20 | 继续抢滩突击,舰炮打击控制点(FIRE ... -> CP-ISLAND),可在虚拟桌面间切换查看三维画面与后台日志。 |
| 7:22 | 登陆兵力抵近控制点,HUD占领进度升至约45%,仍处于land阶段。 |
| 7:26 | 终局裁决。Occupy达到100%,阶段切换为end;HUD显示"RED WINS / 红方胜利",Console输出WINNER red。 |

1 3.6. 总结

KY-RTI的多语言运行支撑能力,使同一HLA联邦内可以协同部署C++动力学、Java条令/规则、Python人工智能与C#的Unity三维态势等异构仿真成员,为构建"可显示、可决策、可对抗"的联合仿真系统提供了坚实基础。Island Assault以夺岛想定完整展示了侦察、打击、抢滩与裁决流程;其中C#三维仿真成员的关键,在于正确加入联邦、在不使用tick模式下完成RTI回调与Unity主线程解耦,以及将对象属性与交互事件可靠映射为GameObject与特效。

KY-RTI的Linux、Windows版本和源码请联系作者:walt_lbq@163.com

KY-RTI分布仿真技术:前 言

KY-RTI分布仿真技术:第一章 简介

KY-RTI分布仿真技术:第二章 系统安装

KY-RTI分布仿真技术:第三章 KY-OMT对象模型模板工具

KY-RTI分布仿真技术:第四章 C++程序设计

KY-RTI分布仿真技术:第五章 Qt程序设计

KY-RTI分布仿真技术:第六章 Java程序设计

KY-RTI分布仿真技术:第七章 Visual C++程序设计

KY-RTI分布仿真技术:第八章 Visual C#程序设计

KY-RTI分布仿真技术:第九章 综合演示

KY-RTI分布仿真技术:第十章 Python程序设计

KY-RTI分布仿真技术:第十一章 人工智能大模型仿真--低空无人机巡逻实战示例

KY-RTI分布仿真技术:第十二章 HLA联邦保存与恢复--仿真中的热恢复与冷恢复

KY-RTI分布仿真技术:第十三章 基于Unity的多语言三维态势仿真--以Island Assault(夺岛突击)想定为例

KY-RTI分布仿真技术:附录1 分组聊天(HLA数据分发管理的应用

KY-RTI分布仿真技术:附录2 大联邦(构建1000个成员的HLA/RTI仿真系统)

KY-RTI分布仿真技术:附录3 国产化(操作系统+CPUs)

相关推荐
ellis19704 小时前
C#/Unity清理非托管资源
unity·c#
玖玥拾20 小时前
Unity 3D 笔记(十四)Unity/C# Socket 网络笔记3
服务器·网络·unity·c#
Python私教1 天前
Godot图片怎么导入?PNG、压缩、Mipmap与Reimport一次讲清
游戏引擎·godot
玖玥拾1 天前
Unity 3D 笔记(十七)Unity/C# Socket 网络笔记6
服务器·网络·unity·c#
寒水馨1 天前
Linux下载、安装godot-4.7.1-stable(附安装包Godot_v4.7.1-stable_linux.x86_64.zip)
linux·游戏引擎·godot·游戏开发·2d游戏·3d游戏·godot engine
寒水馨1 天前
macOS下载、安装godot-4.7.1-stable(附安装包Godot_v4.7.1-stable_macos.universal.zip)
macos·3d·游戏引擎·godot·跨平台·游戏开发·2d
zh路西法1 天前
【10天速通ROS2-PX4无人机】(一) 从零搭建仿真环境,妈妈再也不用担心我炸机了!
无人机·仿真·px4·ros2·gazebo
云上码厂2 天前
热转导仿真与分析
仿真
电子云与长程纠缠2 天前
UE中使用TGuardValue与TInlineComponentArray数据结构
开发语言·数据结构·学习·ue5·游戏引擎