using DG.Tweening; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using AdamThinkDevicesData; using AdamSync; using System.Linq; using static InterfaceManager; using Newtonsoft.Json; using PData; public enum WRJModel { 无人机, 光学无人机, 电子侦察无人机, 自杀式无人机 } /// /// 单个无人机蜂群控制 /// public class UnmannedAerialVehicleManage : MonoBehaviour { public WRJModel wrjModel = WRJModel.无人机; /// /// 无人机状态 /// 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 = 500; // /// /// 是否正在攻击目标 /// public bool isEngagedTarget = false; /// /// 光学无人机 /// public Camera gxWRJCamera; #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() { MatrixFormation(30, 1); for (int i = 0; i < unmannedAerialVehicles.Count; i++) { unmannedAerialVehicles[i].serialNumber = (i + 1).ToString(); } unmannedAerialVehicleManages.Add(this); equipmentCommon = GetComponent(); //Formation(1);//默认阵型 // 订阅布尔值变化事件 OnActivationChanged += OnActivationChangedHandler; } [ContextMenu("Test")] public void Test() { MatrixFormation(30, 1);//根据想定数据去设置无人机数量 } // Update is called once per frame void Update() { if (isStartRehearsing && equipmentCommon.isPlayer) { switch (pattern) { case Pattern.待机: break; case Pattern.警戒: SelectiveAttackDrone(); break; case Pattern.攻击: SelectiveAttackDrone(); if (airRoute) { StartMoveObjectAlongPath(); } break; } } var _unmannedAerialVehicle = unmannedAerialVehicles.FindAll(x => x != null && x.gameObject.activeSelf); if (_unmannedAerialVehicle.Count == 0) { string nowData = string.Format("{0},{1}", "SetToBeDestroyed", equipmentCommon.deviceID); //Debug.Log(nowData); _ = SyncCreateRoom.SendMessageAsync(string.Format("send2room {0}", nowData)); UploadLog(equipmentCommon.deviceID); WWWForm headers = new WWWForm(); headers.AddField("id", equipmentCommon.deviceID); StartCoroutine(PostString(Url_Deletepracticedevicedetail, headers, data => { //Debug.Log(data); Destroy(gameObject); })); } } /// ///上传日志 /// /// public void UploadLog(string deviceID) { string currentTime = System.DateTime.Now.ToString(); List uploadLogMains = new List(); UploadLogMain uploadLogMain = new UploadLogMain(); uploadLogMain.PracticeId = GlobalFlag.practiceSubjectID; uploadLogMain.ThinkId = GlobalFlag.currentThinkId; string log = currentTime + " " + equipmentCommon.equipmentType + "(" + deviceID + ")" + "被成建制销毁了 "; uploadLogMain.log = log; uploadLogMains.Add(uploadLogMain); string uploadLogMainJson = JsonConvert.SerializeObject(uploadLogMains); WWWForm wWWForm = new WWWForm(); wWWForm.AddField("data", uploadLogMainJson); //Debug.Log(uploadLogMainJson); StartCoroutine(PostString(Url_Addpracticelog, wWWForm, data => { Debug.Log(data); })); } /// /// 模式切换 /// public void modeSwitch(int patternCut) { switch (patternCut) { case 0://待机 pattern = Pattern.待机; break; case 1: pattern = Pattern.警戒; break; case 2: pattern = Pattern.攻击; break; default: break; } } public Action> WRJAttach; public void SwitchWRJModel() { gxWRJCamera.gameObject.SetActive(false); switch (wrjModel) { case WRJModel.光学无人机: gxWRJCamera.gameObject.SetActive(true); break; case WRJModel.电子侦察无人机: WRJAttach += SetCollider4WRJ; break; case WRJModel.自杀式无人机: break; } } public List attackColliders1 = new List(); /// /// 攻击打击 /// private void SelectiveAttackDrone() { //if (isEngagedTarget) return; if (wrjModel == WRJModel.电子侦察无人机 || wrjModel == WRJModel.光学无人机) { List allColliders = Physics.OverlapSphere(transform.position, detectionRadius).ToList(); // 检索范围内的所有碰撞体 for (int i = 0; i < allColliders.Count; i++) { if (allColliders[i].gameObject.tag == "AttackTarget" && !allColliders[i].isTrigger && !attackColliders1.Contains(allColliders[i])) attackColliders1.Add(allColliders[i]); } } if (wrjModel == WRJModel.电子侦察无人机) { WRJAttach.Invoke(attackColliders1); } if (wrjModel == WRJModel.光学无人机) { for (int i = 0; i < attackColliders1.Count; i++) { if (attackColliders1[i] == null) attackColliders1.RemoveAt(i); } if (attackColliders1.Count > 0) { var highPriorityTargets = attackColliders1.FindAll(x => x.transform.GetComponent()); if (highPriorityTargets.Count > 0) { //SendMsg(highPriorityTargets[0].transform); unmannedAerialVehicles[0].AttAck(highPriorityTargets[0].transform); } else{ //SendMsg(attackColliders1[0].transform); unmannedAerialVehicles[0].AttAck(attackColliders1[0].transform); } //for (int i = 0; i < attackColliders1.Count; i++) //{ // Collider c = null; // if (attackColliders1[i] != null) // { // c = attackColliders1[i]; // } // if (unmannedAerialVehicles[0]&&unmannedAerialVehicles[0].attackTarget == null) // { // SendMsg(c.transform); // unmannedAerialVehicles[0].AttAck(c.transform); // } //} } } } public Collider currentCollider; public void SetCollider4WRJ(List attackColliders) { DeviceManager.Instance.SetCollider4WRJ(attackColliders, ref currentCollider); if (currentCollider != null) SendMsg(currentCollider.transform); } public void SendMsg(Transform attackTarget) { string nowData = GetSyncData(attackTarget); Debug.Log(nowData); //_ = SyncCreateRoom.SendMessageAsync(string.Format("send2room {0}", nowData)); DeviceManager.Instance.send2roomStr.Enqueue(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) { SenceInfo currentSceneInfo = new SenceInfo(); currentSceneInfo = UIBootstrap.Instance.currentSceneInfo.data; 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; break; case "RCS:": RCS = weaponitemone[i].para_value; break; case "卫星定位频点:": //satellitePositioningFrequency = weaponitemone[i].para_value; switch (weaponitemone[i].para_value) { case "0": satellitePositioningFrequency = "1227.60MHz"; break; case "1": satellitePositioningFrequency = "1381.05MHz"; break; case "2": satellitePositioningFrequency = "1575.42MHz"; break; default: break; } break; case "数据链通信频点:": //dataLinkCommunicationFrequency = weaponitemone[i].para_value; switch (weaponitemone[i].para_value) { case "0": dataLinkCommunicationFrequency = "2GHz"; break; case "1": dataLinkCommunicationFrequency = "4GHz"; break; case "2": dataLinkCommunicationFrequency = "5GHz"; break; default: break; } break; case "电子侦察能力:": //electronicReconnaissanceCapability = weaponitemone[i].para_value; switch (weaponitemone[i].para_value) { case "0": electronicReconnaissanceCapability = "UHF"; break; case "1": electronicReconnaissanceCapability = "L"; break; case "2": electronicReconnaissanceCapability = "S"; break; case "3": electronicReconnaissanceCapability = "C"; break; case "4": electronicReconnaissanceCapability = "X"; break; case "5": electronicReconnaissanceCapability = "Ku"; break; case "6": electronicReconnaissanceCapability = "Ka"; break; default: break; } break; case "光学侦察能力:": //opticalReconnaissanceCapability = weaponitemone[i].para_value; switch (weaponitemone[i].para_value) { case "0": opticalReconnaissanceCapability = "有"; break; case "1": opticalReconnaissanceCapability = "无"; break; default: break; } break; default: break; } if (string.IsNullOrEmpty(currentSceneInfo.EnvWindSpeed)) { ///根据风得速度改变无人机得速度 FireSpeed = float.Parse(maximumFlyingSpeed) / float.Parse(currentSceneInfo.EnvWindSpeed); /////如果风速大于6级,无人机停止飞行 if (float.Parse(currentSceneInfo.EnvWindSpeed) * 10 > 6) { FireSpeed = 0; } } CheckRSC(); if (i == (weaponitemone.Count - 1)) { StartCoroutine(WeaponitemoneDataAddition()); } SwitchWRJModel(); } } /// /// 设置tips颜色 /// public void SetTipsColor() { if (equipmentCommon.isPlayer) unmannedAerialVehicles[0].tips.color = Color.green; else unmannedAerialVehicles[0].tips.color = Color.red; } /// /// 雷达检测无人机身上得RSC /// public void CheckRSC() { if (string.IsNullOrEmpty(RCS)) { float rcs = float.Parse(RCS); if (rcs <= 0.5 && rcs >= 0.1) { StartCoroutine(ShowRadarTips(0.8f, 2)); } else if (rcs >= 0.5f && rcs <= 1) { StartCoroutine(ShowRadarTips(0.4f, 1)); } } } /// /// 多少时间在对方雷达界面上显示红色标记 /// /// /// /// private IEnumerator ShowRadarTips(float minTime, float maxTime) { GameObject tips = transform.Find("Minimapwrj").gameObject; while (true) { tips.gameObject.SetActive(false); float time = UnityEngine.Random.Range(minTime, maxTime); yield return new WaitForSeconds(time); tips.gameObject.SetActive(true); } } /// /// 检测无线电频率 /// /// 无线电数据 /// 驱离或者迫降 public void CheckSatellitePositioningFrequency(Transform target, string interferenceMode, string transmittedPower, string interferingFrequency, string interferenceAngle, LayerMask ground) { if (transmittedPower == "10~30W" || transmittedPower == "30~50W") { if (satellitePositioningFrequency == interferingFrequency) { if (interferenceMode == "驱离") { transform.DOKill(); transform.LookAt(new Vector3(-500, 160, 1600)); transform.DOMove(new Vector3(-500, 160, 1600), 60); } else if (interferenceMode == "迫降") { transform.DOKill(); RaycastHit hit; if (Physics.Raycast(transform.position, Vector3.down, out hit, Mathf.Infinity, ground)) { if (hit.distance > 1f) { hit.point = new Vector3(hit.point.x, hit.point.y + 3, hit.point.z); transform.DOMove(hit.point, 6); } } } } } if (transmittedPower == "50~100W") { if (dataLinkCommunicationFrequency == interferingFrequency) { Vector3 one = transform.position - target.transform.position; float angue = Vector3.Angle(one, target.transform.forward); if (float.Parse(interferenceAngle) >= angue) { maximumFlyingSpeed = (float.Parse(maximumFlyingSpeed) - 5).ToString(); } } } } /// /// 单个无人机数据写入 /// /// IEnumerator WeaponitemoneDataAddition() { yield return new WaitForSeconds(0.01f); for (int i = 0; i < unmannedAerialVehicles.Count; i++) { UnmannedAerialVehicle uav = unmannedAerialVehicles[i]; if (uav != null) { uav.unmannedAerialVehicleManage = this; uav.batteryLife = batteryLife; uav.classificationWindResistance = classificationWindResistance; uav.maximumFlyingSpeed = maximumFlyingSpeed; uav.RCS = RCS; uav.satellitePositioningFrequency = satellitePositioningFrequency; uav.dataLinkCommunicationFrequency = dataLinkCommunicationFrequency; uav.electronicReconnaissanceCapability = electronicReconnaissanceCapability; uav.opticalReconnaissanceCapability = opticalReconnaissanceCapability; uav.wrjModel = wrjModel; if (uav.tips != null) uav.tips.text = wrjModel.ToString(); } } } #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); } } /// /// 根据想定数据去设置无人机数量 /// public void MatrixFormation(int rows, int wrjCount) { for (int i = 0; i < unmannedAerialVehicles.Count; i++) { unmannedAerialVehicles[i].gameObject.SetActive(false); } for (int i = 0; i < wrjCount; i++) { unmannedAerialVehicles[i].gameObject.SetActive(true); } 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, -(wrjCount - 1)); box.size = new Vector3(cols * 2, 1, 2 * wrjCount); } } bool CanDivideEvenly(int dividend, int divisor) { return dividend % divisor == 0; } #endregion /// /// 关闭航线设置 /// public void TurnOffCourseSettings() { if (airRoute) { DistanceMeasurement distanceMeasurement = airRoute.GetComponent(); if (distanceMeasurement) { distanceMeasurement.isPathCanBePlanned = false; } } } /// /// 开启航线设置 /// public void RouteSettings() { if (airRoute) { DistanceMeasurement distanceMeasurement = airRoute.GetComponent(); if (distanceMeasurement) { distanceMeasurement.isPathCanBePlanned = true; positions.Clear(); } } else { GameObject _object = Instantiate(LinePrefab); airRoute = _object; airRoute.transform.position = Vector3.zero; DistanceMeasurement distanceMeasurement = airRoute.GetComponent(); if (distanceMeasurement) { distanceMeasurement.isPathCanBePlanned = true; distanceMeasurement.markers[0] = transform; distanceMeasurement.unmannedAerialVehicleManage = this; } } } private bool isMove = true; /// /// 按规划路径开始移动 /// public void StartMoveObjectAlongPath() { if (isMove && positions.Count > 0) { isMove = false; Vector3 _positions = positions.Dequeue(); var nowData = GetSyncData(_positions); //_ = SyncCreateRoom.SendMessageAsync(string.Format("send2room {0}", nowData)); DeviceManager.Instance.send2roomStr.Enqueue(nowData); StartCoroutine(MoveObjectAlongPath(_positions)); // 启动协程,按规划的路线移动物体 } } public 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(targetPosition); transform.DOMove(targetPosition, _time).SetEase(Ease.Linear); yield return new WaitForSeconds(_time); // 等待一帧时间 isMove = true; } public IEnumerator MoveObjectAlongPath(Vector3 _positions, bool _isMove) // 协程:按路线移动物体 { Vector3 targetPosition = new Vector3(_positions.x, 200, _positions.z);// 目标位置为当前顶点坐标 float _distance = Vector3.Distance(transform.position, targetPosition); float _time = _distance / FireSpeed; transform.LookAt(targetPosition); transform.DOMove(targetPosition, _time).SetEase(Ease.Linear); yield return new WaitForSeconds(_time); // 等待一帧时间 equipmentCommon.isMove = _isMove; } /// /// 无人机整体位置传递 /// /// protected string GetSyncData(Vector3 _positions) { return string.Format("{0},{1},{2},{3},{4}", "DronePosition", equipmentCommon.deviceID, _positions.x, _positions.y, _positions.z); } private void OnDestroy() { StopCoroutine(ShowRadarTips(0, 0)); OnActivationChanged -= OnActivationChangedHandler; Destroy(airRoute.gameObject); } } public enum Pattern { 待机, 警戒, 攻击 }