701 lines
18 KiB
Markdown
701 lines
18 KiB
Markdown
# 第三方引擎集成示例
|
||
|
||
本目录包含了将ThreatSource仿真系统与第三方引擎集成的示例代码。这些示例展示了如何使用适配器模式将不同的游戏引擎与仿真系统进行集成。
|
||
|
||
## 系统要求
|
||
|
||
- .NET 8.0 或更高版本
|
||
- ThreatSource.dll 库文件
|
||
- 对应的第三方引擎开发环境
|
||
|
||
## 示例文件
|
||
|
||
### [UEExample.cs](UEExample.cs)
|
||
|
||
虚幻引擎(Unreal Engine)集成示例,展示了:
|
||
|
||
- 虚幻引擎与ThreatSource仿真系统的双向通信
|
||
- Actor与仿真实体的映射和同步
|
||
- 事件的发布和订阅
|
||
- 坐标系转换和数据适配
|
||
|
||
#### 核心功能
|
||
|
||
```csharp
|
||
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](UnityExample.cs) - 方法一示例
|
||
|
||
**适用于:直接引用.NET库方式**
|
||
|
||
Unity引擎集成示例,展示了:
|
||
|
||
- Unity引擎与ThreatSource仿真系统的双向通信
|
||
- GameObject与仿真实体的映射和转换
|
||
- MonoBehaviour生命周期管理
|
||
- 事件系统的使用和视觉效果处理
|
||
|
||
**使用前提:**
|
||
- 已将 `ThreatSource.dll` 复制到 `Assets/Plugins/`
|
||
- 配置文件已放置在 `Assets/StreamingAssets/ThreatSource/`
|
||
|
||
#### 核心功能
|
||
|
||
```csharp
|
||
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](UnityPackageExample.cs) - 方法二示例
|
||
|
||
**适用于:Unity Package方式**
|
||
|
||
Unity Package集成示例,展示了:
|
||
|
||
- Package级别的管理和配置
|
||
- ThreatSourceUnity命名空间的使用
|
||
- Package专用的事件系统和API
|
||
- Assembly Definition环境下的集成
|
||
|
||
**使用前提:**
|
||
- 已按照方法二创建完整的Package结构
|
||
- 配置了正确的package.json和Assembly Definition
|
||
- 通过Package Manager安装或本地引用Package
|
||
|
||
#### Package核心功能
|
||
|
||
```csharp
|
||
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库(推荐)
|
||
|
||
**适用场景:**
|
||
- 快速原型开发
|
||
- 单一项目使用
|
||
- 需要完整仿真功能访问
|
||
|
||
**操作步骤:**
|
||
|
||
1. **下载并解压库文件**
|
||
```bash
|
||
# 下载 ThreatSourceLibrary-{version}.zip
|
||
# 解压到临时目录
|
||
```
|
||
|
||
2. **复制核心库文件**
|
||
```
|
||
# 将以下文件复制到 Unity 项目
|
||
ThreatSource.dll → Assets/Plugins/
|
||
ThreatSource.deps.json → Assets/Plugins/
|
||
ThreatSource.xml → Assets/Plugins/ (可选,用于智能提示)
|
||
```
|
||
|
||
3. **复制配置文件**
|
||
```
|
||
# 将配置目录复制到 StreamingAssets
|
||
data/ → Assets/StreamingAssets/ThreatSource/data/
|
||
```
|
||
|
||
4. **配置Unity项目设置**
|
||
```csharp
|
||
// 在 Project Settings 中设置:
|
||
// - Api Compatibility Level: .NET Standard 2.1 或更高
|
||
// - Scripting Backend: Mono 或 IL2CPP
|
||
```
|
||
|
||
5. **验证集成**
|
||
```csharp
|
||
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
|
||
|
||
**创建步骤:**
|
||
|
||
1. **创建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
|
||
```
|
||
|
||
2. **配置package.json**
|
||
```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"
|
||
}
|
||
}
|
||
```
|
||
|
||
3. **创建Assembly Definition**
|
||
```json
|
||
// Runtime/ThreatSourceUnity.asmdef
|
||
{
|
||
"name": "ThreatSourceUnity",
|
||
"rootNamespace": "ThreatSourceUnity",
|
||
"references": ["Unity.Mathematics"],
|
||
"includePlatforms": [],
|
||
"excludePlatforms": [],
|
||
"allowUnsafeCode": false
|
||
}
|
||
```
|
||
|
||
4. **创建编辑器工具**
|
||
```csharp
|
||
// 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")}");
|
||
}
|
||
}
|
||
```
|
||
|
||
5. **添加示例代码**
|
||
```csharp
|
||
// 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](UnityExample.cs) | 直接使用ThreatSource命名空间,简单直接 |
|
||
| **方法二:Unity Package** | [UnityPackageExample.cs](UnityPackageExample.cs) | 使用ThreatSourceUnity命名空间,Package化管理 |
|
||
|
||
**使用建议:**
|
||
- 初学者或快速验证概念:参考 `UnityExample.cs`
|
||
- 正式项目开发:参考 `UnityPackageExample.cs`
|
||
- 两个示例文件都包含完整的集成代码,可直接复制使用
|
||
|
||
## 使用说明
|
||
|
||
### 基本集成流程
|
||
|
||
1. **初始化仿真系统**
|
||
```csharp
|
||
_simulationManager = new SimulationManager();
|
||
_dataManager = new ThreatSourceDataManager();
|
||
_simulationManager.StartSimulation(timeStep);
|
||
```
|
||
|
||
2. **订阅仿真事件**
|
||
```csharp
|
||
_simulationManager.Subscribe<MissileFireEvent>(OnMissileFireEvent);
|
||
_simulationManager.Subscribe<MissileExplodeEvent>(OnMissileExplodeEvent);
|
||
_simulationManager.Subscribe<FlightPhaseChangeEvent>(OnFlightPhaseChangeEvent);
|
||
```
|
||
|
||
3. **创建实体映射**
|
||
```csharp
|
||
// 创建仿真实体
|
||
var missile = new InfraredImagingTerminalGuidanceMissile(id, data);
|
||
_simulationManager.RegisterEntity(missile);
|
||
|
||
// 创建引擎对象(Unity GameObject 或 Unreal Actor)
|
||
var visualObject = CreateVisualObject(missile);
|
||
|
||
// 建立映射关系
|
||
_entityMappings[id] = visualObject;
|
||
```
|
||
|
||
4. **同步状态**
|
||
```csharp
|
||
private void SyncEntityStates()
|
||
{
|
||
foreach (var kvp in _entityMappings)
|
||
{
|
||
var entity = _simulationManager.GetEntity(kvp.Key);
|
||
var visualObject = kvp.Value;
|
||
|
||
// 同步位置和朝向
|
||
SyncTransform(entity, visualObject);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 坐标系转换
|
||
|
||
#### Unity集成
|
||
```csharp
|
||
// ThreatSource -> Unity 坐标转换
|
||
gameObject.transform.position = new Vector3(
|
||
entity.KState.Position.X,
|
||
entity.KState.Position.Z, // Unity使用Y作为高度
|
||
entity.KState.Position.Y
|
||
);
|
||
```
|
||
|
||
#### 虚幻引擎集成
|
||
```csharp
|
||
// ThreatSource -> Unreal 坐标转换(右手系 -> 左手系)
|
||
var location = new Vector3(
|
||
entity.KState.Position.X,
|
||
-entity.KState.Position.Y, // Y轴翻转
|
||
entity.KState.Position.Z
|
||
);
|
||
```
|
||
|
||
### 事件处理
|
||
|
||
#### 导弹发射事件
|
||
```csharp
|
||
private void OnMissileFireEvent(MissileFireEvent evt)
|
||
{
|
||
// 播放发射特效
|
||
var visualObject = GetVisualObject(evt.SenderId);
|
||
PlayLaunchEffect(visualObject);
|
||
}
|
||
```
|
||
|
||
#### 导弹爆炸事件
|
||
```csharp
|
||
private void OnMissileExplodeEvent(MissileExplodeEvent evt)
|
||
{
|
||
// 播放爆炸特效
|
||
PlayExplosionEffect(evt.Position);
|
||
|
||
// 销毁视觉对象
|
||
DestroyVisualObject(evt.SenderId);
|
||
}
|
||
```
|
||
|
||
#### 飞行阶段变化事件
|
||
```csharp
|
||
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等第三方引擎
|
||
|
||
### 实体映射
|
||
|
||
在仿真系统和游戏引擎之间建立实体对应关系:
|
||
|
||
```csharp
|
||
// 映射关系管理
|
||
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);
|
||
}
|
||
```
|
||
|
||
### 事件系统
|
||
|
||
统一的事件处理机制:
|
||
|
||
```csharp
|
||
// 事件订阅
|
||
_simulationManager.Subscribe<TEvent>(handler);
|
||
|
||
// 事件处理
|
||
private void HandleEvent(TEvent evt)
|
||
{
|
||
// 转换为引擎特定的操作
|
||
ConvertToEngineOperation(evt);
|
||
}
|
||
```
|
||
|
||
## 性能优化
|
||
|
||
### 批量更新
|
||
```csharp
|
||
// 批量同步实体状态,减少单次调用开销
|
||
private void BatchSyncEntities()
|
||
{
|
||
var entities = _simulationManager.GetAllEntities();
|
||
foreach (var entity in entities)
|
||
{
|
||
if (_entityMappings.TryGetValue(entity.Id, out var visualObject))
|
||
{
|
||
SyncEntity(entity, visualObject);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 距离剔除
|
||
```csharp
|
||
// 只同步视野范围内的实体
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 帧率控制
|
||
```csharp
|
||
// 控制仿真更新频率
|
||
private float _lastUpdateTime;
|
||
private float _updateInterval = 0.02f; // 50Hz
|
||
|
||
private void Update()
|
||
{
|
||
if (Time.time - _lastUpdateTime >= _updateInterval)
|
||
{
|
||
_simulationManager.UpdateSimulation();
|
||
SyncEntityStates();
|
||
_lastUpdateTime = Time.time;
|
||
}
|
||
}
|
||
```
|
||
|
||
## 注意事项
|
||
|
||
### 通用注意事项
|
||
|
||
1. **线程安全**:确保仿真更新和引擎渲染在正确的线程中执行
|
||
2. **性能优化**:合理控制同步频率,避免过度更新
|
||
3. **资源管理**:正确处理实体的创建和销毁
|
||
4. **异常处理**:添加完整的异常处理机制
|
||
|
||
### Unity特定注意事项
|
||
|
||
1. **主线程操作**:Unity API必须在主线程中调用
|
||
2. **生命周期管理**:正确处理MonoBehaviour的生命周期
|
||
3. **预制体管理**:合理组织和加载预制体资源
|
||
4. **坐标系转换**:注意Unity的左手坐标系
|
||
|
||
### 虚幻引擎特定注意事项
|
||
|
||
1. **蓝图集成**:考虑与蓝图系统的集成
|
||
2. **Actor生命周期**:正确管理Actor的创建和销毁
|
||
3. **坐标系转换**:处理右手系到左手系的转换
|
||
4. **性能分析**:使用虚幻引擎的性能分析工具
|
||
|
||
## 扩展功能
|
||
|
||
### 多人同步
|
||
```csharp
|
||
// 网络同步支持
|
||
public class NetworkedThreatSourceAdapter
|
||
{
|
||
public void SyncEntityOverNetwork(string entityId, EntityState state)
|
||
{
|
||
// 通过网络同步实体状态
|
||
NetworkManager.SendEntityUpdate(entityId, state);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 录制回放
|
||
```csharp
|
||
// 仿真录制和回放
|
||
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);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 自定义渲染
|
||
```csharp
|
||
// 自定义渲染效果
|
||
public class CustomMissileRenderer
|
||
{
|
||
public void RenderMissileTrail(Vector3 position, Vector3 velocity)
|
||
{
|
||
// 根据导弹状态渲染自定义拖尾效果
|
||
var trailLength = velocity.magnitude * 0.1f;
|
||
RenderTrail(position, velocity.normalized, trailLength);
|
||
}
|
||
}
|
||
```
|