using System.Collections.Generic; using System.IO; using CounterDrone.Core; using CounterDrone.Core.Algorithms; using CounterDrone.Core.Models; using CounterDrone.Core.Repository; using CounterDrone.Core.Services; using UnityEngine; using UVector3 = UnityEngine.Vector3; using AVector3 = CounterDrone.Core.Algorithms.Vector3; namespace CounterDrone.Unity { /// 一键启动:创建想定 → 推荐方案 → 运行仿真 public class SimulationBootstrap : MonoBehaviour { [Header("Simulation Settings")] [SerializeField] private float _droneSpeed = 200f; [SerializeField] private float _routeLength = 20000f; [SerializeField] private float _timeScale = 4f; public SimulationRunner Runner { get; private set; } void Start() { var paths = new UnityPathProvider(); // 清理上次残留数据 if (System.IO.File.Exists(paths.GetMainDbPath())) System.IO.File.Delete(paths.GetMainDbPath()); if (System.IO.Directory.Exists(paths.GetFramesDir())) System.IO.Directory.Delete(paths.GetFramesDir(), true); var dbm = new DatabaseManager(paths); var db = dbm.OpenMainDb(); foreach (var a in DefaultAmmunition.GetAll()) db.Insert(a); // 创建想定 var scenario = new ScenarioService( new SimTaskRepository(db), new CombatSceneRepository(db), new ControlZoneRepository(db), new TargetConfigRepository(db), new EquipmentDeploymentRepository(db), new CloudDispersalRepository(db), new RoutePlanRepository(db), new WaypointRepository(db)); var task = scenario.CreateTask("Unity Demo", ""); var taskId = task.Id; scenario.SaveScene(taskId, new CombatScene { SceneType = (int)SceneType.Plain, WindSpeed = 3, WindDirection = (int)WindDirection.W, Temperature = 22, }); scenario.SaveTarget(taskId, new TargetConfig { GroupId = "default", TargetType = (int)TargetType.Piston, PowerType = (int)PowerType.Piston, Quantity = 1, TypicalSpeed = _droneSpeed, TypicalAltitude = 500, }); scenario.SaveRoute(taskId, "default", new RoutePlan { FormationMode = (int)FormationMode.Single }, new List { new Waypoint { PosX = 0, PosY = 500, PosZ = 0, Speed = _droneSpeed }, new Waypoint { PosX = _routeLength, PosY = 500, PosZ = 0, Speed = _droneSpeed }, }); // 推荐方案 var detail = scenario.GetTaskDetail(taskId); var ammoCatalog = db.Table().ToList(); var planner = new DefaultDefensePlanner(ammoCatalog); var droneGroup = new DroneGroup { GroupId = "default", Target = detail.Targets[0], Route = detail.Routes[0], Waypoints = detail.WaypointGroups["default"], }; var fireUnits = new List(); for (int i = 0; i < 8; i++) fireUnits.Add(new FireUnit { Id = $"u{i}", Type = PlatformType.GroundBased, Position = new AVector3(5000 + i * 50, 0, 50), MuzzleVelocity = 800, TotalMunitions = 3, AmmoTypes = new() { AerosolType.InertGas, AerosolType.ActiveMaterial, AerosolType.ActiveFuel }, }); var result = planner.Plan(fireUnits, new List { droneGroup }, detail.Scene); scenario.SaveCloudDispersal(taskId, new CloudDispersal { PositionX = (droneGroup.Waypoints[0].PosX + droneGroup.Waypoints[^1].PosX) / 2, PositionY = (droneGroup.Waypoints[0].PosY + droneGroup.Waypoints[^1].PosY) / 2, PositionZ = (droneGroup.Waypoints[0].PosZ + droneGroup.Waypoints[^1].PosZ) / 2, DisperseHeight = droneGroup.Target.TypicalAltitude, Source = "Algorithm", }); var equips = new List(); foreach (var u in fireUnits) equips.Add(new EquipmentDeployment { EquipmentRole = (int)EquipmentRole.LaunchPlatform, PlatformType = (int)u.Type, Quantity = 1, PositionX = u.Position.X, PositionY = u.Position.Y, PositionZ = u.Position.Z, AerosolType = (int)u.AmmoTypes[0], MunitionCount = u.TotalMunitions, Cooldown = u.Cooldown, MuzzleVelocity = u.MuzzleVelocity, CruiseSpeed = u.CruiseSpeed > 0 ? u.CruiseSpeed : null, ReleaseAltitude = u.ReleaseAltitude > 0 ? u.ReleaseAltitude : null, }); scenario.SaveDeployment(taskId, equips); db.Close(); var plan = result.Best; Debug.Log($"规划方案: {plan.ThreatsEngaged} 威胁被分配, {plan.MergedSchedule.Count} 发, 概率 {plan.OverallProbability:P0}"); // 运行仿真 Runner = GetComponent(); if (Runner == null) Runner = gameObject.AddComponent(); else Runner.enabled = true; Runner.Engine.SetFireSchedule(plan.MergedSchedule); Runner.LoadAndStart(taskId); // 设置倍速 if (Runner.Engine != null) { Runner.Engine.TimeScale = _timeScale; Debug.Log($"Engine state: {Runner.Engine.State}, drones: {Runner.Engine.Drones.Count}"); } // 移动 Game 视图相机 var cam = Camera.main; if (cam == null) { var cgo = new GameObject("MainCamera"); cgo.AddComponent(); cam = cgo.GetComponent(); cam.tag = "MainCamera"; } cam.transform.position = new UVector3(_routeLength / 2f, 2000, -3000); cam.transform.LookAt(new UVector3(_routeLength / 2f, 500, 0)); Debug.Log("Camera positioned. In Scene view, double-click 'Simulation' in Hierarchy to focus."); } } }