You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
7.6 KiB
239 lines
7.6 KiB
4 years ago
|
using AX.InputSystem;
|
||
|
using AX.NetworkSystem;
|
||
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
|
||
|
//[RequireComponent(typeof(Rigidbody))]
|
||
|
/// <summary>
|
||
|
/// 油罐爆炸
|
||
|
/// </summary>
|
||
|
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<OilTanksCooling> 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<Rigidbody>())
|
||
|
{
|
||
|
//给定爆炸力大小,爆炸点,爆炸半径
|
||
|
//利用刚体组件添加爆炸力AddExplosionForce
|
||
|
hits.GetComponent<Rigidbody>().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>();
|
||
|
// 获取所有轻伤员
|
||
|
BaseHaemalController[] trappedPerson = GameObject.Find("P_AllParent/P_Disasters/P_TrappedPerson").GetComponentsInChildren<BaseHaemalController>();
|
||
|
// 获取所有伤员
|
||
|
List<BaseHaemalController> allPerson = new List<BaseHaemalController>();
|
||
|
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<BaseGameObjInfo>())
|
||
|
{
|
||
|
arg.gameObjID = NomalModel.transform.GetComponent<BaseGameObjInfo>().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<CloneGameObjInfo>().gameObjType == CloneObjType.LiquidLevel)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
public class OilTanksExplodeManager
|
||
|
{
|
||
|
static Dictionary<string, OilTanksExplode> OilTanksExplodes = new Dictionary<string, OilTanksExplode>();
|
||
|
|
||
|
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;
|
||
|
}
|