24 KiB
24 KiB
第三方引擎集成示例
本目录包含了将ThreatSource仿真系统与第三方引擎集成的示例代码。这些示例展示了如何使用适配器模式将不同的游戏引擎与仿真系统进行集成。
系统要求
- .NET 8.0 或更高版本
- ThreatSource.dll 库文件
- 对应的第三方引擎开发环境
- Unity:2020.3或更高版本
- Unreal Engine:4.27或更高版本
- Matlab/Simulink:R2019b或更高版本(需要.NET 8.0支持)
示例文件
SimulinkExample.cs
Matlab/Simulink集成示例,展示了:
- 基于.NET Assembly直接调用的Matlab/Simulink集成
- 简化的API接口,便于Matlab调用
- 实时仿真数据交换和时间同步
- 与Simulink时间步长的协调
核心功能
using ThreatSource.Simulation;
using ThreatSource.Data;
using ThreatSource.Missile;
using ThreatSource.Equipment;
using ThreatSource.Utils;
/// <summary>
/// Matlab/Simulink适配器类,演示如何将威胁源库集成到Matlab/Simulink中
/// </summary>
public class MatlabSimulinkAdapter
{
private ISimulationManager _simulationManager;
private ThreatSourceDataManager _dataManager;
private Dictionary<string, object> _matlabEntities;
public bool StartSimulation(double timeStep = 0.01)
{
_simulationManager.StartSimulation(timeStep);
return true;
}
public bool CreateTarget(string entityId, double posX, double posY, double posZ,
double velX, double velY, double velZ)
{
var targetPos = new Vector3D(posX, posY, posZ);
var targetVel = new Vector3D(velX, velY, velZ);
var tank = new Tank(entityId, tankProperties, tankInitialMotion, _simulationManager);
_simulationManager.RegisterEntity(entityId, tank);
return true;
}
public double[] GetEntityState(string entityId)
{
// 返回 [x,y,z,vx,vy,vz,roll,pitch,yaw,isActive] 格式
var entity = _simulationManager.GetEntityById(entityId);
return ConvertToMatlabStateArray(entity);
}
}
Matlab调用示例
详见 matlab_example.m 文件,展示了完整的Matlab集成流程:
%% 加载威胁源库
NET.addAssembly('ThreatSource.dll');
%% 创建适配器
adapter = MatlabSimulinkAdapter();
%% 启动仿真
success = adapter.StartSimulation(0.01); % 10ms时间步长
%% 创建目标和导弹
adapter.CreateTarget('target_001', 5000, 0, 1000, -50, 0, 0);
adapter.CreateIRMissile('missile_001', 0, 0, 100, 'target_001');
%% 仿真循环
for i = 1:1000
adapter.UpdateSimulation(0.01);
missile_state = adapter.GetEntityState('missile_001');
% 处理数据...
end
Simulink S-Function集成
详见本文档的"Matlab/Simulink集成"部分,获取完整的Simulink集成指南,包括:
- S-Function封装
- 实时数据可视化
- 与Simulink Control System闭环仿真
- 性能优化和故障排除
UEExample.cs
虚幻引擎(Unreal Engine)集成示例,展示了:
- 虚幻引擎与ThreatSource仿真系统的双向通信
- Actor与仿真实体的映射和同步
- 事件的发布和订阅
- 坐标系转换和数据适配
核心功能
using ThreatSource.Simulation;
using ThreatSource.Data;
using ThreatSource.Missile;
public class UnrealThreatSourceAdapter
{
private ISimulationManager _simulationManager;
private ThreatSourceDataManager _dataManager;
private Dictionary<string, object> _entityActors;
public void UpdateSimulation()
{
// 更新仿真
_simulationManager.UpdateSimulation();
// 同步实体状态到虚幻引擎Actor
SyncEntityStates();
}
public string CreateMissile(string missileType, Vector3 location, string targetId)
{
// 从配置创建导弹
var missileData = _dataManager.GetMissile(missileType);
var missile = new InfraredImagingTerminalGuidanceMissile(missileId, missileData);
// 在虚幻引擎中创建Actor
var missileActor = _unrealEngine.SpawnActor("BP_Missile", location, rotation);
// 建立映射关系
_entityActors[missileId] = missileActor;
return missileId;
}
}
UnityExample.cs - 方法一示例
适用于:直接引用.NET库方式
Unity引擎集成示例,展示了:
- Unity引擎与ThreatSource仿真系统的双向通信
- GameObject与仿真实体的映射和转换
- MonoBehaviour生命周期管理
- 事件系统的使用和视觉效果处理
使用前提:
- 已将
ThreatSource.dll复制到Assets/Plugins/ - 配置文件已放置在
Assets/StreamingAssets/ThreatSource/
核心功能
using ThreatSource.Simulation;
using ThreatSource.Data;
using ThreatSource.Missile;
using UnityEngine;
public class UnityThreatSourceAdapter : MonoBehaviour
{
private ISimulationManager _simulationManager;
private ThreatSourceDataManager _dataManager;
private Dictionary<string, GameObject> _entityGameObjects;
private void Update()
{
// 更新仿真
_simulationManager.UpdateSimulation();
// 同步实体状态到Unity GameObject
SyncEntityStates();
}
public void CreateMissile(string missileType, Vector3 position, string targetId)
{
// 从配置创建导弹
var missileData = _dataManager.GetMissile(missileType);
var missile = new InfraredImagingTerminalGuidanceMissile(missileId, missileData);
// 在Unity中创建GameObject
var missileGameObject = Instantiate(missilePrefab, position, Quaternion.identity);
// 建立映射关系
_entityGameObjects[missileId] = missileGameObject;
}
}
UnityPackageExample.cs - 方法二示例
适用于:Unity Package方式
Unity Package集成示例,展示了:
- Package级别的管理和配置
- ThreatSourceUnity命名空间的使用
- Package专用的事件系统和API
- Assembly Definition环境下的集成
使用前提:
- 已按照方法二创建完整的Package结构
- 配置了正确的package.json和Assembly Definition
- 通过Package Manager安装或本地引用Package
Package核心功能
using ThreatSourceUnity;
public class PackageExampleUsage : MonoBehaviour
{
private void Start()
{
var packageManager = ThreatSourcePackageManager.Instance;
// 创建目标
string targetId = packageManager.CreateTarget(
"package_target_001",
new Vector3(1000, 0, 100),
new Vector3(-50, 0, 0)
);
// 创建导弹
string missileId = packageManager.CreateMissile(
"IR_Missile_Example",
Vector3.zero,
targetId
);
}
}
Unity集成方式
Unity引擎与ThreatSource仿真库提供两种主要的集成方式,开发者可以根据项目需求和团队情况选择合适的方案。
方法一:直接引用.NET库(推荐)
适用场景:
- 快速原型开发
- 单一项目使用
- 需要完整仿真功能访问
操作步骤:
-
下载并解压库文件
# 下载 ThreatSourceLibrary-{version}.zip # 解压到临时目录 -
复制核心库文件
# 将以下文件复制到 Unity 项目 ThreatSource.dll → Assets/Plugins/ ThreatSource.deps.json → Assets/Plugins/ ThreatSource.xml → Assets/Plugins/ (可选,用于智能提示) -
复制配置文件
# 将配置目录复制到 StreamingAssets data/ → Assets/StreamingAssets/ThreatSource/data/ -
配置Unity项目设置
// 在 Project Settings 中设置: // - Api Compatibility Level: .NET Standard 2.1 或更高 // - Scripting Backend: Mono 或 IL2CPP -
验证集成
using ThreatSource.Simulation; using ThreatSource.Data; public class ThreatSourceTest : MonoBehaviour { private void Start() { // 测试库是否正确加载 var dataManager = new ThreatSourceDataManager(); Debug.Log("ThreatSource库加载成功!"); } }
优势:
- ✅ 实现简单,快速上手
- ✅ 直接访问完整API
- ✅ 性能最优,无额外包装
- ✅ 易于调试和问题排查
劣势:
- ❌ 文件管理相对分散
- ❌ 版本更新需手动替换文件
- ❌ 难以在多项目间共享
方法二:创建Unity Package
适用场景:
- 团队协作开发
- 多项目复用
- 需要版本管理
- 计划发布到Package Registry
创建步骤:
-
创建Package目录结构
Assets/ThreatSourceUnity/ ├── package.json ├── README.md ├── CHANGELOG.md ├── Runtime/ │ ├── ThreatSourceUnity.asmdef │ ├── Scripts/ │ │ ├── UnityThreatSourceAdapter.cs │ │ ├── ThreatSourceManager.cs │ │ └── Utils/ │ │ ├── CoordinateConverter.cs │ │ └── ConfigLoader.cs │ └── Plugins/ │ ├── ThreatSource.dll │ └── ThreatSource.deps.json ├── Editor/ │ ├── ThreatSourceUnity.Editor.asmdef │ └── ThreatSourceSetup.cs └── Samples~/ └── BasicExample/ └── ThreatSourceExample.cs -
配置package.json
{ "name": "com.yourcompany.threatsource", "version": "1.1.22", "displayName": "ThreatSource Library", "description": "军事威胁源仿真库Unity集成包", "unity": "2020.3", "dependencies": { "com.unity.mathematics": "1.2.6" }, "keywords": ["simulation", "missile", "guidance"], "author": { "name": "Your Company", "email": "support@company.com" } } -
创建Assembly Definition
// Runtime/ThreatSourceUnity.asmdef { "name": "ThreatSourceUnity", "rootNamespace": "ThreatSourceUnity", "references": ["Unity.Mathematics"], "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false } -
创建编辑器工具
// Editor/ThreatSourceSetup.cs using UnityEngine; using UnityEditor; using System.IO; public class ThreatSourceSetup : EditorWindow { [MenuItem("Tools/ThreatSource/Package Setup")] static void ShowWindow() { GetWindow<ThreatSourceSetup>("ThreatSource Setup"); } private void OnGUI() { GUILayout.Label("ThreatSource Package Configuration", EditorStyles.boldLabel); if (GUILayout.Button("Setup StreamingAssets")) { SetupStreamingAssets(); } if (GUILayout.Button("Validate Configuration")) { ValidateSetup(); } } private void SetupStreamingAssets() { string targetPath = "Assets/StreamingAssets/ThreatSource"; if (!Directory.Exists(targetPath)) { Directory.CreateDirectory(targetPath); Debug.Log($"Created directory: {targetPath}"); } } private void ValidateSetup() { // 验证配置完整性 bool isValid = File.Exists("Assets/StreamingAssets/ThreatSource/data"); Debug.Log($"Setup validation: {(isValid ? "PASSED" : "FAILED")}"); } } -
添加示例代码
// Samples~/BasicExample/ThreatSourceExample.cs using UnityEngine; using ThreatSource.Simulation; using ThreatSource.Data; namespace ThreatSourceUnity.Samples { public class ThreatSourceExample : MonoBehaviour { private UnityThreatSourceAdapter adapter; private void Start() { adapter = GetComponent<UnityThreatSourceAdapter>(); if (adapter == null) { adapter = gameObject.AddComponent<UnityThreatSourceAdapter>(); } CreateExampleScene(); } private void CreateExampleScene() { // 创建示例仿真场景 adapter.CreateTarget("target1", new Vector3(1000, 0, 0), Vector3.zero); adapter.CreateMissile("Hellfire", Vector3.zero, "target1"); } } }
优势:
- ✅ 更好的项目组织和结构
- ✅ 便于版本管理和更新
- ✅ 支持团队协作和共享
- ✅ 可发布到Package Registry
- ✅ 包含完整的文档和示例
劣势:
- ❌ 初始设置相对复杂
- ❌ 需要Package管理知识
- ❌ 可能增加项目复杂度
集成方式选择指导
| 因素 | 直接引用.NET库 | 创建Unity Package |
|---|---|---|
| 项目规模 | 小型、原型项目 | 中大型、生产项目 |
| 团队规模 | 个人、小团队 | 多人团队 |
| 版本管理 | 手动管理 | Package Manager |
| 复用需求 | 单项目使用 | 多项目复用 |
| 上手难度 | 简单 | 中等 |
| 维护成本 | 低 | 中等 |
推荐选择:
- 🚀 快速原型/学习:选择方法一
- 🏢 团队项目/生产环境:选择方法二
- 🔄 从方法一迁移到方法二:随项目成熟度逐步升级
示例文件对应关系
| 集成方式 | 示例文件 | 主要特点 |
|---|---|---|
| 方法一:直接引用.NET库 | UnityExample.cs | 直接使用ThreatSource命名空间,简单直接 |
| 方法二:Unity Package | UnityPackageExample.cs | 使用ThreatSourceUnity命名空间,Package化管理 |
使用建议:
- 初学者或快速验证概念:参考
UnityExample.cs - 正式项目开发:参考
UnityPackageExample.cs - 两个示例文件都包含完整的集成代码,可直接复制使用
使用说明
基本集成流程
-
初始化仿真系统
_simulationManager = new SimulationManager(); _dataManager = new ThreatSourceDataManager(); _simulationManager.StartSimulation(timeStep); -
订阅仿真事件
_simulationManager.Subscribe<MissileFireEvent>(OnMissileFireEvent); _simulationManager.Subscribe<MissileExplodeEvent>(OnMissileExplodeEvent); _simulationManager.Subscribe<FlightPhaseChangeEvent>(OnFlightPhaseChangeEvent); -
创建实体映射
// 创建仿真实体 var missile = new InfraredImagingTerminalGuidanceMissile(id, data); _simulationManager.RegisterEntity(missile); // 创建引擎对象(Unity GameObject 或 Unreal Actor) var visualObject = CreateVisualObject(missile); // 建立映射关系 _entityMappings[id] = visualObject; -
同步状态
private void SyncEntityStates() { foreach (var kvp in _entityMappings) { var entity = _simulationManager.GetEntity(kvp.Key); var visualObject = kvp.Value; // 同步位置和朝向 SyncTransform(entity, visualObject); } }
坐标系转换
Unity集成
// ThreatSource -> Unity 坐标转换
gameObject.transform.position = new Vector3(
entity.KState.Position.X,
entity.KState.Position.Z, // Unity使用Y作为高度
entity.KState.Position.Y
);
虚幻引擎集成
// ThreatSource -> Unreal 坐标转换(右手系 -> 左手系)
var location = new Vector3(
entity.KState.Position.X,
-entity.KState.Position.Y, // Y轴翻转
entity.KState.Position.Z
);
事件处理
导弹发射事件
private void OnMissileFireEvent(MissileFireEvent evt)
{
// 播放发射特效
var visualObject = GetVisualObject(evt.SenderId);
PlayLaunchEffect(visualObject);
}
导弹爆炸事件
private void OnMissileExplodeEvent(MissileExplodeEvent evt)
{
// 播放爆炸特效
PlayExplosionEffect(evt.Position);
// 销毁视觉对象
DestroyVisualObject(evt.SenderId);
}
飞行阶段变化事件
private void OnFlightPhaseChangeEvent(FlightPhaseChangeEvent evt)
{
var visualObject = GetVisualObject(evt.SenderId);
switch (evt.NewPhase)
{
case FlightPhase.Boost:
ShowBoostEffect(visualObject);
break;
case FlightPhase.Terminal:
ShowTerminalEffect(visualObject);
break;
}
}
关键概念
适配器模式
适配器模式用于连接ThreatSource仿真系统和第三方引擎:
- 仿真层:ThreatSource核心仿真逻辑
- 适配器层:数据转换和事件映射
- 引擎层:Unity/Unreal等第三方引擎
实体映射
在仿真系统和游戏引擎之间建立实体对应关系:
// 映射关系管理
private Dictionary<string, VisualObject> _entityMappings;
// 创建映射
public void CreateEntityMapping(string entityId, VisualObject visualObject)
{
_entityMappings[entityId] = visualObject;
}
// 同步状态
public void SyncEntity(string entityId)
{
var entity = _simulationManager.GetEntity(entityId);
var visualObject = _entityMappings[entityId];
// 同步位置、朝向、状态等
SyncTransform(entity, visualObject);
SyncVisualState(entity, visualObject);
}
事件系统
统一的事件处理机制:
// 事件订阅
_simulationManager.Subscribe<TEvent>(handler);
// 事件处理
private void HandleEvent(TEvent evt)
{
// 转换为引擎特定的操作
ConvertToEngineOperation(evt);
}
性能优化
批量更新
// 批量同步实体状态,减少单次调用开销
private void BatchSyncEntities()
{
var entities = _simulationManager.GetAllEntities();
foreach (var entity in entities)
{
if (_entityMappings.TryGetValue(entity.Id, out var visualObject))
{
SyncEntity(entity, visualObject);
}
}
}
距离剔除
// 只同步视野范围内的实体
private void SyncVisibleEntities(Vector3 viewerPosition, float maxDistance)
{
foreach (var kvp in _entityMappings)
{
var entity = _simulationManager.GetEntity(kvp.Key);
var distance = Vector3.Distance(entity.KState.Position, viewerPosition);
if (distance <= maxDistance)
{
SyncEntity(entity, kvp.Value);
}
}
}
帧率控制
// 控制仿真更新频率
private float _lastUpdateTime;
private float _updateInterval = 0.02f; // 50Hz
private void Update()
{
if (Time.time - _lastUpdateTime >= _updateInterval)
{
_simulationManager.UpdateSimulation();
SyncEntityStates();
_lastUpdateTime = Time.time;
}
}
注意事项
通用注意事项
- 线程安全:确保仿真更新和引擎渲染在正确的线程中执行
- 性能优化:合理控制同步频率,避免过度更新
- 资源管理:正确处理实体的创建和销毁
- 异常处理:添加完整的异常处理机制
Unity特定注意事项
- 主线程操作:Unity API必须在主线程中调用
- 生命周期管理:正确处理MonoBehaviour的生命周期
- 预制体管理:合理组织和加载预制体资源
- 坐标系转换:注意Unity的左手坐标系
虚幻引擎特定注意事项
- 蓝图集成:考虑与蓝图系统的集成
- Actor生命周期:正确管理Actor的创建和销毁
- 坐标系转换:处理右手系到左手系的转换
- 性能分析:使用虚幻引擎的性能分析工具
扩展功能
多人同步
// 网络同步支持
public class NetworkedThreatSourceAdapter
{
public void SyncEntityOverNetwork(string entityId, EntityState state)
{
// 通过网络同步实体状态
NetworkManager.SendEntityUpdate(entityId, state);
}
}
录制回放
// 仿真录制和回放
public class SimulationRecorder
{
public void RecordFrame(float timestamp, List<EntityState> states)
{
// 记录当前帧的所有实体状态
_recordedFrames.Add(new SimulationFrame(timestamp, states));
}
public void PlaybackFrame(int frameIndex)
{
// 回放指定帧的状态
var frame = _recordedFrames[frameIndex];
ApplyFrameStates(frame);
}
}
自定义渲染
// 自定义渲染效果
public class CustomMissileRenderer
{
public void RenderMissileTrail(Vector3 position, Vector3 velocity)
{
// 根据导弹状态渲染自定义拖尾效果
var trailLength = velocity.magnitude * 0.1f;
RenderTrail(position, velocity.normalized, trailLength);
}
}
Matlab/Simulink集成
Matlab/Simulink特定注意事项
- 版本兼容性:确保Matlab版本支持.NET 8.0(R2019b或更高版本)
- 时间同步:使用固定步长求解器确保时间同步准确性
- 数据类型转换:注意.NET数组与Matlab数组之间的转换
- S-Function集成:在Simulink中使用S-Function封装威胁源库调用
Matlab集成示例
基本初始化
%% 加载威胁源库
NET.addAssembly('ThreatSource.dll');
%% 创建适配器
adapter = MatlabSimulinkAdapter();
adapter.StartSimulation(0.01);
实时仿真循环
%% 仿真主循环
for step = 1:1000
% 更新仿真
adapter.UpdateSimulation(0.01);
% 获取实体状态
missile_state = adapter.GetEntityState('missile_001');
target_state = adapter.GetEntityState('target_001');
% 数据处理和可视化
if ~isempty(missile_state)
updateVisualization(missile_state, target_state);
end
end
S-Function封装
function [sys,x0,str,ts,simStateCompliance] = threat_source_sfun(t,x,u,flag)
% 威胁源库S-Function包装器
switch flag,
case 0,
[sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes;
case 3,
sys = mdlOutputs(t,x,u);
case 9,
sys = mdlTerminate(t,x,u);
end
function [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes
% 初始化S-Function
global threat_adapter;
if isempty(threat_adapter)
NET.addAssembly('ThreatSource.dll');
threat_adapter = MatlabSimulinkAdapter();
threat_adapter.StartSimulation(0.01);
end
function sys = mdlOutputs(t,x,u)
% 输出实体状态数据
global threat_adapter;
threat_adapter.UpdateSimulation(0.01);
missile_state = threat_adapter.GetEntityState('missile_001');
sys = double(missile_state);
Simulink模型集成步骤
- 添加S-Function块:在Simulink模型中添加S-Function块
- 配置参数:设置S-Function名称为
threat_source_sfun - 连接数据流:将S-Function输出连接到显示或分析模块
- 配置求解器:使用固定步长求解器,时间步长设为0.01秒
数据格式规范
实体状态数组格式
索引 | 含义 | 单位
-----|-------------------|------
0-2 | 位置(x,y,z) | 米
3-5 | 速度(vx,vy,vz) | 米/秒
6-8 | 姿态(roll,pitch,yaw) | 弧度
9 | 活动状态 | 0/1
Matlab示例完整流程
参见 matlab_example.m 了解完整的集成流程,包括:
- 系统初始化和库加载
- 仿真场景创建
- 实时数据获取和处理
- 结果可视化和分析
- 资源清理和异常处理
文件结构
docs/examples/Integration/
├── README.md # 本文档
├── SimulinkExample.cs # Matlab/Simulink集成示例代码
├── matlab_example.m # Matlab调用示例脚本
├── UnityExample.cs # Unity集成示例代码(方法一)
├── UnityPackageExample.cs # Unity Package集成示例代码(方法二)
└── UEExample.cs # 虚幻引擎集成示例代码
相关文档
- 威胁源库文档:../../README.md - 库的基本使用说明
- API文档:../../api/ - 详细的API参考文档
- 变更日志:../../CHANGELOG.md - 版本更新记录