using AX.InputSystem; using AX.NetworkSystem; using System.Collections.Generic; using UnityEngine; //[RequireComponent(typeof(Rigidbody))] /// /// 油罐爆炸 /// public class OilTanksExplode : MonoBehaviour { // 是否发生爆炸 public bool IsExplode = false; // 罐体是否受热,冷却强度是否足够 public bool IsHeating = false; //// 热负荷,需要的冷却强度-千焦/小时 /3600千焦/秒 //public float HeatLoad = 3600f; // 爆炸音效-音效 public AudioClip ExplodeAudio; // 正常罐模型 public GameObject NomalModel; // 爆炸罐模型 public GameObject ExplodeModel; // 受到的爆炸力 private float power = 2000f; private Vector3 explosionPos; private float radius = 20f; public GameObject particle; // 冷却组件 public List Coolings; // 罐体信息 public OilTankMessage OilData; private void Awake() { OilTanksExplodeManager.AddOilTanksExplode(gameObject.name, this); } private void OnDestroy() { OilTanksExplodeManager.RemoveOilTanksExplode(gameObject.name); } public void Explode(Vector3 point) { NomalModel.SetActive(false); ExplodeModel.SetActive(true); //Vector3 point = transform.position + new Vector3(Random.Range(-6, 6), 6, Random.Range(-6, 6)); //得到碰撞点的坐标 //实例化出这个物体 Instantiate(particle, point, Quaternion.Euler(new Vector3(-90, 0, 0))); //Physics.OverlapSphere():球体投射,给定一个球心和半径,返回球体投射到的物体的碰撞器 Collider[] colliders = Physics.OverlapSphere(point, radius); foreach (Collider hits in colliders) //遍历碰撞器数组 { //如果这个物体有刚体组件 if (hits.GetComponent()) { //给定爆炸力大小,爆炸点,爆炸半径 //利用刚体组件添加爆炸力AddExplosionForce hits.GetComponent().AddExplosionForce(power, point, radius); } } // 如果是导调组,创建 if (CurrentUserInfo.role == Role.导调组) { // 如果没有生成全页面火 if (!CheckHaveLiquidLevel()) { CloneLiquidLevelFire(NomalModel.transform.position + new Vector3(0, 10, 0)); } // 对伤员造成伤害 HurtOnMan(); } } private void HurtOnMan() { // 获取所有重伤员 BaseHaemalController[] wounded = GameObject.Find("P_AllParent/P_Disasters/P_Wounded").GetComponentsInChildren(); // 获取所有轻伤员 BaseHaemalController[] trappedPerson = GameObject.Find("P_AllParent/P_Disasters/P_TrappedPerson").GetComponentsInChildren(); // 获取所有伤员 List allPerson = new List(); allPerson.AddRange(wounded); allPerson.AddRange(trappedPerson); // 检测伤员与爆炸的距离 foreach (var item in allPerson) { float distance = Vector3.Distance(transform.position, item.transform.position); if (distance <= OilData.ExplodeDeadRange) { item.Haemal = 0; } else if (distance <= OilData.ExplodeHurtRange) { if (item.Haemal > 50) { item.Haemal = 50; } } } } public void CloneLiquidLevelFire(Vector3 pos) { var arg = new CloneCmdArgs(); if (NomalModel.transform.GetComponent()) { arg.gameObjID = NomalModel.transform.GetComponent().GameObjID; } arg.cloneObjType = CloneObjType.LiquidLevel; arg.hitPos = pos; CloneCommand.Instance.Execute(EntitiesManager.Instance.CreateObjID(CurrentUserInfo.mySelf.Id), arg); } private float time = 0; void Update() { // 导调组,非灾情库模式,未爆炸 if (GameSettings.othersSettings.mode != Mode.DisasterManagement && CurrentUserInfo.role == Role.导调组 && !IsExplode && GameSettings.othersSettings.isStartDrill ) { // 检查周围是否有火源 SearchNearUnits(); // 检查罐体是否正在受热 CheckIsHeating(); if (IsHeating) { time += Time.deltaTime; } if (time >= OilData.ExplodeTime * 60) { // 罐体可以发生爆炸 if (OilData.IsCanExplode) { IsExplode = true; foreach (var item in Coolings) { item.IsOver = true; } Vector3 point = transform.position + new Vector3(Random.Range(-6, 6), 6, Random.Range(-6, 6)); ExplodeData data = new ExplodeData() { Name = gameObject.name, Point = point }; NetworkManager.Default.SendAsync("OLITANKS_EXPLODE_SYNC", data); } } } } private void CheckIsHeating() { IsHeating = false; foreach (var item in Coolings) { if (item.IsHeating) { if (item.IsCooling == false) { IsHeating = true; } } } } // 查询附近火源 public void SearchNearUnits() { Collider[] colliders = Physics.OverlapSphere(transform.position, 20f, 1 << LayerMask.NameToLayer("Thermal")); if (colliders.Length > 0) { //IsHeating = true; foreach (var item in Coolings) { item.IsHeating = true; item.SetCoolingObject(); } } else { foreach (var item in Coolings) { item.IsHeating = false; } //IsHeating = false; } } // 检测是否存在全液面火 public bool CheckHaveLiquidLevel() { Vector3 position = transform.position + new Vector3(0, 10, 0); Collider[] colliders = Physics.OverlapSphere(position, 5f, 1 << LayerMask.NameToLayer("Thermal")); if (colliders.Length > 0) { // 远近由索引限定 for (int i = 0; i < colliders.Length; i++) { if (colliders[i].GetComponent().gameObjType == CloneObjType.LiquidLevel) { return true; } } } return false; } } public class OilTanksExplodeManager { static Dictionary OilTanksExplodes = new Dictionary(); public static void AddOilTanksExplode(string name, OilTanksExplode oilTanksExplode) { if (!OilTanksExplodes.ContainsKey(name)) { OilTanksExplodes.Add(name, oilTanksExplode); } } public static void RemoveOilTanksExplode(string name) { if (OilTanksExplodes.ContainsKey(name)) { OilTanksExplodes.Remove(name); } } public static void OilTanksExplodeByName(string name, Vector3 point) { if (OilTanksExplodes.ContainsKey(name)) { OilTanksExplodes[name].Explode(point); } } } public class ExplodeData { public string Name; public Vector3 Point; }