using DG.Tweening; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using AdamThinkDevicesData; using AdamSync; using System.Linq; /// /// 单个无人机蜂群控制 /// public class UnmannedAerialVehicleManage : MonoBehaviour { /// /// 无人机状态 /// public Pattern pattern = Pattern.待机; public static List unmannedAerialVehicleManages = new List(); #region 启动暂停 private bool _isStartRehearsing = false; /// /// 是否正在预演 /// public bool isStartRehearsing { get { return _isStartRehearsing; } set { if (_isStartRehearsing != value) { _isStartRehearsing = value; OnActivationChanged?.Invoke(_isStartRehearsing); } } } /// /// 布尔值变化时触发的事件 /// public event System.Action OnActivationChanged; /// /// 间隔时间 /// public float interval = 5.0f; #endregion public EquipmentCommon equipmentCommon; /// /// 无人机预制体 /// public GameObject UAVPrefab; /// /// 编队无人机数量 /// public int totalObjects = 30; // 总共的物体数量 /// /// 所有子物体无人机 /// public List unmannedAerialVehicles = new List(); /// /// 线预制体 /// public GameObject LinePrefab; /// /// 航线 /// public GameObject airRoute; /// /// 已有路径 /// public Queue positions = new Queue(); public Vector3 endPosition = new Vector3(); /// /// 飞行速度 /// public float FireSpeed = 20.0f; /// /// 检测范围半径 /// public float detectionRadius = 50; // /// /// 是否正在攻击目标 /// public bool isEngagedTarget = false; #region 无人机数据 /// /// 续航时间 /// public string batteryLife; /// /// 抗风等级 /// public string classificationWindResistance; /// /// 最大飞行速度 /// public string maximumFlyingSpeed; /// /// RCS /// public string RCS; /// /// 卫星定位频点 /// public string satellitePositioningFrequency; /// /// 数据链通信频点 /// public string dataLinkCommunicationFrequency; /// /// 电子侦察能力 /// public string electronicReconnaissanceCapability; /// /// 光学侦察能力 /// public string opticalReconnaissanceCapability; #endregion // Start is called before the first frame update void Start() { for (int i = 0; i < unmannedAerialVehicles.Count; i++) { unmannedAerialVehicles[i].serialNumber = (i + 1).ToString(); } unmannedAerialVehicleManages.Add(this); equipmentCommon = GetComponent(); Formation(1);//默认阵型 // 订阅布尔值变化事件 OnActivationChanged += OnActivationChangedHandler; } // Update is called once per frame void Update() { if (isStartRehearsing && equipmentCommon.isPlayer && pattern == Pattern.攻击) { if (airRoute) { StartMoveObjectAlongPath(); } } if (equipmentCommon.isPlayer &&isStartRehearsing) { switch (pattern) { case Pattern.待机: break; case Pattern.警戒: SelectiveAttackDrone(); break; case Pattern.攻击: SelectiveAttackDrone(); break; } } } /// /// 模式切换 /// public void modeSwitch(int patternCut) { switch (patternCut) { case 0://待机 pattern = Pattern.待机; break; case 1: pattern = Pattern.警戒; break; case 2: pattern = Pattern.攻击; break; default: break; } } /// /// 攻击打击 /// private void SelectiveAttackDrone() { if (isEngagedTarget) return; List colliders = Physics.OverlapSphere(transform.position, detectionRadius).ToList(); // 检索范围内的所有碰撞体 List colliders1 = new List(); for (int i=0;i< colliders.Count; i++) { if (colliders[i].transform.tag == "AttackTarget") colliders1.Add(colliders[i]); } if (colliders1.Count > 0) { isEngagedTarget = true; colliders1.ForEach(x => Debug.Log(x.transform.name)); int _number = UnityEngine.Random.Range(0, colliders1.Count - 1); List _unmannedAerialVehicles = unmannedAerialVehicles.FindAll(x => x != null); SendMsg(colliders1[_number].transform); for (int i = 0; i < _unmannedAerialVehicles.Count; i++) { _unmannedAerialVehicles[i].AttAck(colliders1[_number].transform); } } } public void SendMsg(Transform attackTarget) { string nowData = GetSyncData(attackTarget); Debug.Log(nowData); _ = SyncCreateRoom.SendMessageAsync(string.Format("send2room {0}", nowData)); } /// /// 无人机攻击目标传递 /// /// protected string GetSyncData(Transform attackTarget) { return string.Format("{0},{1},{2},{3},{4}", "SingleDronePosition", equipmentCommon.deviceID, attackTarget.position.x, attackTarget.position.y, attackTarget.position.z); } #region 启动暂停 /// /// 导条变化调用 /// /// void OnActivationChangedHandler(bool newValue) { if (newValue) { } else { } } #endregion #region 数据写入 /// /// 数据写入 /// /// public void FillInTheData(List weaponitemone) { //if (equipmentCommon) //{ // string msg = $"send2room {equipmentCommon.equipmentType}+{transform.position.ToString().Replace(" ", "").Replace("(", "").Replace(")", "")}+{transform.eulerAngles.ToString().Replace(" ", "").Replace("(", "").Replace(")", "")}"; // Debug.Log(msg); // _ = SyncCreateRoom.SendMessageAsync(msg); //} for (int i = 0; i < weaponitemone.Count; i++) { switch (weaponitemone[i].para_name) { case "续航时间:": batteryLife = weaponitemone[i].para_value; break; case "抗风等级:": classificationWindResistance = weaponitemone[i].para_value; break; case "最大飞行速度:": maximumFlyingSpeed = weaponitemone[i].para_value; FireSpeed = float.Parse(maximumFlyingSpeed); break; case "RCS:": RCS = weaponitemone[i].para_value; break; case "卫星定位频点:": satellitePositioningFrequency = weaponitemone[i].para_value; break; case "数据链通信频点:": dataLinkCommunicationFrequency = weaponitemone[i].para_value; break; case "电子侦察能力:": electronicReconnaissanceCapability = weaponitemone[i].para_value; break; case "光学侦察能力:": opticalReconnaissanceCapability = weaponitemone[i].para_value; break; default: break; } if (i == (weaponitemone.Count - 1)) { StartCoroutine(WeaponitemoneDataAddition()); } } } /// /// 单个无人机数据写入 /// /// IEnumerator WeaponitemoneDataAddition() { yield return new WaitForSeconds(0.01f); for (int i = 0; i < unmannedAerialVehicles.Count; i++) { if (unmannedAerialVehicles[i] != null) { unmannedAerialVehicles[i].unmannedAerialVehicleManage = this; unmannedAerialVehicles[i].batteryLife = batteryLife; unmannedAerialVehicles[i].classificationWindResistance = classificationWindResistance; unmannedAerialVehicles[i].maximumFlyingSpeed = maximumFlyingSpeed; unmannedAerialVehicles[i].RCS = RCS; unmannedAerialVehicles[i].satellitePositioningFrequency = satellitePositioningFrequency; unmannedAerialVehicles[i].dataLinkCommunicationFrequency = dataLinkCommunicationFrequency; unmannedAerialVehicles[i].electronicReconnaissanceCapability = electronicReconnaissanceCapability; unmannedAerialVehicles[i].opticalReconnaissanceCapability = opticalReconnaissanceCapability; } } } #endregion #region 阵型编队 /// /// 阵型选择 /// /// public void Formation(int number) { switch (number) { case 1: GenerateFormation(); break; case 2: MatrixFormation(5); break; case 3: MatrixFormation(30); break; case 4: MatrixFormation(1); break; default: break; } } /// /// 无人机雁式阵型 /// private void GenerateFormation() { int count = 1; // 每一排的物体数量 int currentCount = 0; Vector3 startPos = new Vector3(); for (int i = 0; i < Mathf.Ceil(Mathf.Sqrt(totalObjects)); i++) { //Debug.Log("剩余。。。:" + (totalObjects - currentCount)); startPos = new Vector3(-i * 2, 0, -i * 2); for (int j = 0; j < count; j++)//每排物体个数 { if (currentCount < totalObjects) { Vector3 _vector3 = startPos + new Vector3(j * 2, 0, 0); if (unmannedAerialVehicles[currentCount]) unmannedAerialVehicles[currentCount].transform.localPosition = _vector3; currentCount++; } else { BoxCollider box = transform.GetComponent(); if (box) { box.center = new Vector3(0, 0, -i); box.size = new Vector3(2 * count, 1, 2 * (i + 1)); } } } count += 2; // 下一排增加两个物体 } } /// /// 矩阵阵型 /// private void MatrixFormation(int rows) { float offsetX = 2.0f; // 子物体之间的水平间距 float offsetY = 2.0f; // 子物体之间的垂直间距 float offsetZ = 2.0f; // 子物体之间的垂直间距 int currentCount = 0; int cols = CanDivideEvenly(totalObjects, rows) ? totalObjects / rows : totalObjects / rows + 1; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { if (currentCount < totalObjects) { Vector3 position = new Vector3(col * offsetX, 0, -row * offsetZ); if (unmannedAerialVehicles[currentCount]) unmannedAerialVehicles[currentCount].transform.localPosition = position; currentCount++; } } } BoxCollider box = transform.GetComponent(); if (box) { Debug.Log("cols..:" + cols); Debug.Log("rows..:" + rows); box.center = new Vector3(cols - 1, 0, -(rows - 1)); box.size = new Vector3(cols * 2, 1, 2 * rows); } } bool CanDivideEvenly(int dividend, int divisor) { return dividend % divisor == 0; } #endregion /// /// 关闭航线设置 /// public void TurnOffCourseSettings() { if (airRoute) { ObjectPlanner objectPlanner = airRoute.GetComponent(); if (objectPlanner) { objectPlanner.isPathCanBePlanned = false; } } } /// /// 开启航线设置 /// public void RouteSettings() { if (airRoute) { ObjectPlanner objectPlanner = airRoute.GetComponent(); if (objectPlanner) { objectPlanner.isPathCanBePlanned = true; objectPlanner.lineRenderer.SetVertexCount(0); positions.Clear(); } } else { GameObject _object = Instantiate(LinePrefab); airRoute = _object; airRoute.transform.position = Vector3.zero; ObjectPlanner objectPlanner = airRoute.GetComponent(); if (objectPlanner) { objectPlanner.unmannedAerialVehicleManage = this; objectPlanner.isPathCanBePlanned = true; objectPlanner.SetSelectedObject(transform.gameObject); } } } private bool isMove = true; /// /// 按规划路径开始移动 /// public void StartMoveObjectAlongPath() { if (isMove && positions.Count > 0) { isMove = false; StartCoroutine(MoveObjectAlongPath(positions.Dequeue())); // 启动协程,按规划的路线移动物体 } } IEnumerator MoveObjectAlongPath(Vector3 positions) // 协程:按路线移动物体 { Vector3 targetPosition = new Vector3(positions.x, 150, positions.z);// 目标位置为当前顶点坐标 float _distance = Vector3.Distance(transform.position, targetPosition); float _time = _distance / FireSpeed; transform.LookAt(endPosition); transform.DOMove(targetPosition, _time).SetEase(Ease.Linear); yield return new WaitForSeconds(_time); // 等待一帧时间 isMove = true; } private void OnDestroy() { OnActivationChanged -= OnActivationChangedHandler; } } public enum Pattern { 待机, 警戒, 攻击 }