ThreatSourceLibaray/docs/examples/Integration/UnityPackageExample.cs

595 lines
19 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#if NEVER // 使用编译指令确保此文件永远不会被编译
// Unity Package集成示例代码 - 方法二创建Unity Package
//
// 【适用场景】
// - 团队协作开发和多项目复用
// - 需要版本管理和Package Manager支持
// - 计划发布到Package Registry
//
// 【前置条件】
// 1. 按照Integration README创建完整的Package结构
// 2. 配置正确的package.json和Assembly Definition
// 3. 使用Package Manager安装或本地引用Package
//
// 【Package结构】
// com.yourcompany.threatsource/
// ├── Runtime/
// │ ├── Scripts/(本示例文件应放在此处)
// │ └── Plugins/ThreatSource.dll
// └── Samples~/BasicExample/
//
// 展示如何在Unity Package环境中使用ThreatSource仿真系统
using UnityEngine;
using System.Collections.Generic;
using ThreatSource.Simulation;
using ThreatSource.Data;
using ThreatSource.Missile;
// Package专用命名空间避免与用户代码冲突
namespace ThreatSourceUnity
{
/// <summary>
/// ThreatSource Unity Package管理器
/// 提供Package级别的配置和管理功能
/// </summary>
public class ThreatSourcePackageManager : MonoBehaviour
{
#region
private static ThreatSourcePackageManager _instance;
public static ThreatSourcePackageManager Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<ThreatSourcePackageManager>();
if (_instance == null)
{
GameObject go = new GameObject("ThreatSourcePackageManager");
_instance = go.AddComponent<ThreatSourcePackageManager>();
DontDestroyOnLoad(go);
}
}
return _instance;
}
}
#endregion
#region
[Header("Package配置")]
[SerializeField] private string packageVersion = "1.1.22";
[SerializeField] private bool enableDebugLogging = true;
[SerializeField] private float simulationTimeStep = 0.02f;
[Header("资源路径配置")]
[SerializeField] private string dataPath = "StreamingAssets/ThreatSource/data";
[SerializeField] private string prefabPath = "Packages/com.yourcompany.threatsource/Runtime/Prefabs";
#endregion
#region
private ISimulationManager _simulationManager;
private ThreatSourceDataManager _dataManager;
private Dictionary<string, GameObject> _entityGameObjects = new Dictionary<string, GameObject>();
#endregion
#region Unity生命周期
private void Awake()
{
// 确保单例
if (_instance != null && _instance != this)
{
Destroy(gameObject);
return;
}
_instance = this;
DontDestroyOnLoad(gameObject);
InitializePackage();
}
private void Update()
{
UpdateSimulation();
}
private void OnDestroy()
{
CleanupPackage();
}
#endregion
#region Package初始化
/// <summary>
/// 初始化Package
/// </summary>
private void InitializePackage()
{
try
{
LogDebug($"正在初始化ThreatSource Package v{packageVersion}");
// 验证Package环境
if (!ValidatePackageEnvironment())
{
LogError("Package环境验证失败");
return;
}
// 初始化仿真系统
_simulationManager = new SimulationManager();
_dataManager = new ThreatSourceDataManager();
// 启动仿真
_simulationManager.StartSimulation(simulationTimeStep);
// 订阅事件
SubscribeToEvents();
LogDebug("ThreatSource Package初始化完成");
}
catch (System.Exception ex)
{
LogError($"Package初始化失败: {ex.Message}");
}
}
/// <summary>
/// 验证Package环境
/// </summary>
private bool ValidatePackageEnvironment()
{
// 检查数据路径
string fullDataPath = System.IO.Path.Combine(Application.streamingAssetsPath, "ThreatSource/data");
if (!System.IO.Directory.Exists(fullDataPath))
{
LogError($"数据目录不存在: {fullDataPath}");
return false;
}
// 检查Assembly Definition
if (!HasValidAssemblyDefinition())
{
LogError("Assembly Definition配置无效");
return false;
}
return true;
}
/// <summary>
/// 检查Assembly Definition配置
/// </summary>
private bool HasValidAssemblyDefinition()
{
// 在实际Package中这里可以检查Assembly Definition的配置
// 例如检查引用关系、平台设置等
return true; // 简化示例
}
#endregion
#region
/// <summary>
/// 订阅仿真事件
/// </summary>
private void SubscribeToEvents()
{
_simulationManager.Subscribe<MissileFireEvent>(OnMissileFireEvent);
_simulationManager.Subscribe<MissileExplodeEvent>(OnMissileExplodeEvent);
_simulationManager.Subscribe<FlightPhaseChangeEvent>(OnFlightPhaseChangeEvent);
}
private void OnMissileFireEvent(MissileFireEvent evt)
{
LogDebug($"Package事件: 导弹 {evt.SenderId} 向 {evt.TargetId} 发射");
// 触发Unity事件
ThreatSourceEvents.Instance.OnMissileFired?.Invoke(evt.SenderId, evt.TargetId);
}
private void OnMissileExplodeEvent(MissileExplodeEvent evt)
{
LogDebug($"Package事件: 导弹 {evt.SenderId} 在 {evt.Position} 爆炸");
// 清理GameObject
if (_entityGameObjects.TryGetValue(evt.SenderId, out GameObject missileGO))
{
Destroy(missileGO);
_entityGameObjects.Remove(evt.SenderId);
}
// 触发Unity事件
ThreatSourceEvents.Instance.OnMissileExploded?.Invoke(evt.SenderId,
CoordinateConverter.ThreatSourceToUnity(evt.Position));
}
private void OnFlightPhaseChangeEvent(FlightPhaseChangeEvent evt)
{
LogDebug($"Package事件: 导弹 {evt.SenderId} 进入 {evt.NewPhase} 阶段");
// 触发Unity事件
ThreatSourceEvents.Instance.OnFlightPhaseChanged?.Invoke(evt.SenderId, evt.NewPhase);
}
#endregion
#region 仿
/// <summary>
/// 更新仿真
/// </summary>
private void UpdateSimulation()
{
if (_simulationManager != null)
{
_simulationManager.UpdateSimulation();
SyncEntityStates();
}
}
/// <summary>
/// 同步实体状态
/// </summary>
private void SyncEntityStates()
{
foreach (var kvp in _entityGameObjects)
{
var entity = _simulationManager.GetEntity(kvp.Key);
if (entity?.KState != null)
{
var gameObject = kvp.Value;
gameObject.transform.position = CoordinateConverter.ThreatSourceToUnity(entity.KState.Position);
gameObject.transform.rotation = CoordinateConverter.OrientationToQuaternion(entity.KState.Orientation);
}
}
}
#endregion
#region API
/// <summary>
/// 创建导弹Package API
/// </summary>
public string CreateMissile(string missileType, Vector3 position, string targetId)
{
try
{
var missileData = _dataManager.GetMissile(missileType);
string missileId = $"pkg_missile_{System.Guid.NewGuid():N}";
var missile = new InfraredImagingTerminalGuidanceMissile(missileId, missileData)
{
KState = new KinematicState
{
Position = CoordinateConverter.UnityToThreatSource(position),
Velocity = new ThreatSource.Simulation.Vector3(0, 0, 0),
Orientation = new Orientation(0, 0, 0)
}
};
_simulationManager.RegisterEntity(missile);
// 使用Package资源加载
var prefab = LoadPrefabFromPackage("Missile");
if (prefab != null)
{
var missileGO = Instantiate(prefab, position, Quaternion.identity);
missileGO.name = $"[Package] {missileId}";
var controller = missileGO.GetComponent<PackageMissileController>();
if (controller == null)
{
controller = missileGO.AddComponent<PackageMissileController>();
}
controller.Initialize(missileId, targetId);
_entityGameObjects[missileId] = missileGO;
}
LogDebug($"Package创建导弹: {missileId}");
return missileId;
}
catch (System.Exception ex)
{
LogError($"Package创建导弹失败: {ex.Message}");
return null;
}
}
/// <summary>
/// 创建目标Package API
/// </summary>
public string CreateTarget(string targetId, Vector3 position, Vector3 velocity)
{
try
{
var target = new BaseEquipment(targetId)
{
KState = new KinematicState
{
Position = CoordinateConverter.UnityToThreatSource(position),
Velocity = CoordinateConverter.UnityToThreatSource(velocity),
Orientation = new Orientation(0, 0, 0)
}
};
_simulationManager.RegisterEntity(target);
var prefab = LoadPrefabFromPackage("Target");
if (prefab != null)
{
var targetGO = Instantiate(prefab, position, Quaternion.identity);
targetGO.name = $"[Package] {targetId}";
_entityGameObjects[targetId] = targetGO;
}
LogDebug($"Package创建目标: {targetId}");
return targetId;
}
catch (System.Exception ex)
{
LogError($"Package创建目标失败: {ex.Message}");
return null;
}
}
#endregion
#region
/// <summary>
/// 从Package加载预制体
/// </summary>
private GameObject LoadPrefabFromPackage(string prefabName)
{
// 优先从Package路径加载
string packagePath = $"Packages/com.yourcompany.threatsource/Runtime/Prefabs/{prefabName}";
var prefab = Resources.Load<GameObject>(packagePath);
if (prefab == null)
{
// 后备方案从普通Resources加载
prefab = Resources.Load<GameObject>($"Prefabs/{prefabName}");
}
return prefab;
}
#endregion
#region
/// <summary>
/// 清理Package
/// </summary>
private void CleanupPackage()
{
LogDebug("正在清理ThreatSource Package");
_simulationManager?.StopSimulation();
_simulationManager = null;
foreach (var gameObject in _entityGameObjects.Values)
{
if (gameObject != null)
{
Destroy(gameObject);
}
}
_entityGameObjects.Clear();
LogDebug("ThreatSource Package清理完成");
}
#endregion
#region
private void LogDebug(string message)
{
if (enableDebugLogging)
{
Debug.Log($"[ThreatSourcePackage] {message}");
}
}
private void LogError(string message)
{
Debug.LogError($"[ThreatSourcePackage] {message}");
}
#endregion
}
/// <summary>
/// Package专用的导弹控制器
/// </summary>
public class PackageMissileController : MonoBehaviour
{
private string _missileId;
private string _targetId;
private TrailRenderer _trailRenderer;
private ParticleSystem _thrustEffect;
public void Initialize(string missileId, string targetId)
{
_missileId = missileId;
_targetId = targetId;
// 初始化组件
_trailRenderer = GetComponent<TrailRenderer>();
_thrustEffect = GetComponentInChildren<ParticleSystem>();
// 订阅Package事件
ThreatSourceEvents.Instance.OnFlightPhaseChanged += OnFlightPhaseChanged;
}
private void OnDestroy()
{
// 取消订阅
if (ThreatSourceEvents.Instance != null)
{
ThreatSourceEvents.Instance.OnFlightPhaseChanged -= OnFlightPhaseChanged;
}
}
private void OnFlightPhaseChanged(string missileId, FlightPhase newPhase)
{
if (missileId != _missileId) return;
switch (newPhase)
{
case FlightPhase.Boost:
if (_thrustEffect != null) _thrustEffect.Play();
break;
case FlightPhase.Midcourse:
if (_trailRenderer != null) _trailRenderer.enabled = true;
break;
case FlightPhase.Terminal:
if (_trailRenderer != null) _trailRenderer.material.color = Color.red;
break;
}
}
}
/// <summary>
/// Package事件系统
/// </summary>
public class ThreatSourceEvents : MonoBehaviour
{
private static ThreatSourceEvents _instance;
public static ThreatSourceEvents Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<ThreatSourceEvents>();
if (_instance == null)
{
GameObject go = new GameObject("ThreatSourceEvents");
_instance = go.AddComponent<ThreatSourceEvents>();
DontDestroyOnLoad(go);
}
}
return _instance;
}
}
// Unity Events for Package users
public System.Action<string, string> OnMissileFired;
public System.Action<string, Vector3> OnMissileExploded;
public System.Action<string, FlightPhase> OnFlightPhaseChanged;
}
/// <summary>
/// 坐标系转换工具Package版本
/// </summary>
public static class CoordinateConverter
{
public static Vector3 ThreatSourceToUnity(ThreatSource.Utils.Vector3D position)
{
return new Vector3(
(float)position.X,
(float)position.Z,
(float)position.Y
);
}
public static ThreatSource.Utils.Vector3D UnityToThreatSource(Vector3 position)
{
return new ThreatSource.Utils.Vector3D(
position.x,
position.z,
position.y
);
}
public static Quaternion OrientationToQuaternion(Orientation orientation)
{
return Quaternion.Euler(
(float)(orientation.Pitch * Mathf.Rad2Deg),
(float)(orientation.Yaw * Mathf.Rad2Deg),
(float)(orientation.Roll * Mathf.Rad2Deg)
);
}
}
}
/// <summary>
/// Package使用示例脚本
/// 展示如何在用户项目中使用ThreatSource Package
/// </summary>
namespace ThreatSourceUnity.Samples
{
using ThreatSourceUnity;
public class PackageExampleUsage : MonoBehaviour
{
[Header("示例配置")]
[SerializeField] private bool autoCreateScene = true;
[SerializeField] private float sceneCreationDelay = 2f;
private void Start()
{
if (autoCreateScene)
{
Invoke(nameof(CreateExampleScene), sceneCreationDelay);
}
}
/// <summary>
/// 创建示例场景
/// </summary>
public void CreateExampleScene()
{
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
);
Debug.Log($"Package示例场景创建完成: 导弹 {missileId} -> 目标 {targetId}");
}
/// <summary>
/// 手动创建导弹
/// </summary>
public void CreateMissile()
{
var packageManager = ThreatSourcePackageManager.Instance;
packageManager.CreateMissile("IR_Missile_Example", transform.position, "package_target_001");
}
/// <summary>
/// 订阅Package事件示例
/// </summary>
private void OnEnable()
{
ThreatSourceEvents.Instance.OnMissileFired += OnMissileFired;
ThreatSourceEvents.Instance.OnMissileExploded += OnMissileExploded;
}
private void OnDisable()
{
if (ThreatSourceEvents.Instance != null)
{
ThreatSourceEvents.Instance.OnMissileFired -= OnMissileFired;
ThreatSourceEvents.Instance.OnMissileExploded -= OnMissileExploded;
}
}
private void OnMissileFired(string missileId, string targetId)
{
Debug.Log($"用户项目收到事件: 导弹 {missileId} 向 {targetId} 发射");
}
private void OnMissileExploded(string missileId, Vector3 position)
{
Debug.Log($"用户项目收到事件: 导弹 {missileId} 在 {position} 爆炸");
}
}
}
#endif // 结束编译指令块