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.
830 lines
38 KiB
830 lines
38 KiB
3 years ago
|
using UnityEngine;
|
||
|
using System.Collections;
|
||
|
using AX.TrackRecord;
|
||
|
using System.Collections.Generic;
|
||
|
using AX.MessageSystem;
|
||
|
using System;
|
||
|
|
||
|
public class FireSpreadCtrl : MonoBehaviour
|
||
|
{
|
||
|
|
||
|
private OtherArrribute_Fire fireAttri;
|
||
|
|
||
|
private bool straightSpread;
|
||
|
private bool areaSpread;
|
||
|
private bool aroundSpread;
|
||
|
private int startTime;//单位为分钟
|
||
|
private List<Vector3> pathPointList = new List<Vector3>();
|
||
|
private GameObject fire;
|
||
|
|
||
|
public float spreadSpeed = 4.0f;//蔓延速度
|
||
|
public float repeatRate = 4.0f;
|
||
|
|
||
|
private float distance;
|
||
|
private float spreadDis = 5.0f;
|
||
|
private int result;
|
||
|
private List<Vector3> spreadFirePositions = new List<Vector3>();//直线蔓延火点数组
|
||
|
private int index = 0;
|
||
|
private List<List<Vector3>> spdFirePositions = new List<List<Vector3>>();//区域或四周蔓延火点数组
|
||
|
|
||
|
public bool flag = false;
|
||
|
|
||
|
public bool isSpreading = false;//是否正在蔓延
|
||
|
private RaycastHit hit;
|
||
|
private GameObject FireInfoImage;
|
||
|
private GameObject ConfirmFireSpreadWin;
|
||
|
public GameObject messageBox;
|
||
|
|
||
|
private DateTime startWaitTime;
|
||
|
private DateTime speedChangeTime;
|
||
|
private int changedSpeed;
|
||
|
private TimeSpan RemainingTime;
|
||
|
// Use this for initialization
|
||
|
void Awake()//Start()
|
||
|
{
|
||
|
MessageDispatcher.AddListener("SETFIRE", Execute);
|
||
|
|
||
|
FireInfoImage = GameObject.Find("Canvas").transform.Find("FireInfoImage").gameObject;
|
||
|
ConfirmFireSpreadWin = GameObject.Find("Canvas").transform.Find("ConfirmFireSpreadWin").gameObject;
|
||
|
messageBox = GameObject.Find("Canvas").transform.Find("MessageBox").gameObject;
|
||
|
|
||
|
fire = Resources.Load<GameObject>("Prefabs/ZQPrefab/GroundFire_LG");
|
||
|
|
||
|
//TheBackView.instance.SpeedChangeEvent += OnSpeedChangeEvent;
|
||
|
|
||
|
MessageDispatcher.AddListener("RESETFIRE", Execute1);
|
||
|
|
||
|
MessageDispatcher.AddListener("REGISTERSPEEDCHANGEEVENT", RegisterSpeedChangeEvent);
|
||
|
|
||
|
MessageDispatcher.AddListener("TriggerFireSpread", TriggerFireSpread);
|
||
|
}
|
||
|
|
||
|
private void RegisterSpeedChangeEvent(IMessage msg)
|
||
|
{
|
||
|
if ((string)msg.Sender == this.name)
|
||
|
{
|
||
|
TheBackView.instance.SpeedChangeEvent += OnSpeedChangeEvent;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnSpeedChangeEvent(SpeedChangeEventArgs e)
|
||
|
{
|
||
|
speedChangeTime = DateTime.Now;
|
||
|
|
||
|
if (isSpreading)
|
||
|
{
|
||
|
if (e.speed != 0)
|
||
|
{
|
||
|
CancelInvoke("CtrlFireSpread");//如果已经开始蔓延,播放倍数改变时先取消蔓延方法的执行
|
||
|
spreadSpeed = 4.0f;
|
||
|
repeatRate = 4.0f;
|
||
|
InvokeRepeating("CtrlFireSpread", spreadSpeed / e.speed, repeatRate / e.speed);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CancelInvoke("CtrlFireSpread");//暂停蔓延
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{//还没开始蔓延或者已经蔓延完成(已经蔓延完成不用处理)
|
||
|
if (!flag)
|
||
|
{//还没开始蔓延
|
||
|
if (e.speed != 0)
|
||
|
{
|
||
|
spreadSpeed = 4.0f;
|
||
|
repeatRate = 4.0f;
|
||
|
spreadSpeed = spreadSpeed / e.speed;
|
||
|
repeatRate = repeatRate / e.speed;
|
||
|
|
||
|
if (startWaitTime == DateTime.MinValue)//还没触发开始等时间
|
||
|
{
|
||
|
changedSpeed = e.speed;
|
||
|
}
|
||
|
else
|
||
|
{//已经等待过一段时间
|
||
|
if (RemainingTime.TotalSeconds == 0d)//没有暂停过
|
||
|
{
|
||
|
var timeOffset = speedChangeTime - startWaitTime;//已等待时间
|
||
|
var remainingTime = TimeSpan.FromMinutes(startTime) - timeOffset;//还未等待的时间
|
||
|
|
||
|
//StopCoroutine("WaitSenconds");
|
||
|
StopAllCoroutines();
|
||
|
StartCoroutine(WaitSenconds((float)remainingTime.TotalSeconds / e.speed));
|
||
|
}
|
||
|
else
|
||
|
{//已暂停过
|
||
|
StartCoroutine(WaitSenconds((float)RemainingTime.TotalSeconds / e.speed));
|
||
|
RemainingTime = new TimeSpan();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (startWaitTime != DateTime.MinValue)
|
||
|
{//已经等待过一段时间的暂停处理(还没触发开始等时间的情况,暂停不用做处理)
|
||
|
|
||
|
var timeOffset = speedChangeTime - startWaitTime;//已等待时间
|
||
|
RemainingTime = TimeSpan.FromMinutes(startTime) - timeOffset;//还未等待的时间
|
||
|
|
||
|
//StopCoroutine("WaitSenconds");
|
||
|
StopAllCoroutines();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void Execute(IMessage msg)
|
||
|
{
|
||
|
if ((string)msg.Sender == this.name)
|
||
|
{
|
||
|
//各种加载的情况下控制火的蔓延
|
||
|
fireAttri = (OtherArrribute_Fire)msg.Data;
|
||
|
|
||
|
if (!isSpreading)
|
||
|
{
|
||
|
if (fireAttri.PathPointList.Count > 0)
|
||
|
{
|
||
|
if (!flag)
|
||
|
{
|
||
|
straightSpread = fireAttri.StraightSpread;
|
||
|
areaSpread = fireAttri.AreaSpread;
|
||
|
aroundSpread = fireAttri.AroundSpread;
|
||
|
startTime = fireAttri.StartTime;
|
||
|
pathPointList = fireAttri.PathPointList;
|
||
|
|
||
|
if (pathPointList.Count > 0)
|
||
|
GetSpreadFirePositions();//获取火蔓延生成火的所有位置
|
||
|
|
||
|
if (!(ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CopyQuestion))
|
||
|
{
|
||
|
if (straightSpread || areaSpread || aroundSpread)
|
||
|
{
|
||
|
Transform pfire = GameObject.Find("pfire").transform;
|
||
|
if (straightSpread)
|
||
|
{
|
||
|
bool isSpreaded = false;
|
||
|
//控制index,以控制蔓延过火后重新设置路径(接着以前路径增加)后,接着蔓延;
|
||
|
//若是换蔓延方式或者重置路径后再重新设置路径,则从头开始蔓延
|
||
|
foreach (Transform child in pfire)
|
||
|
{
|
||
|
if (child.GetComponent<SpreadedFire>() && child.GetComponent<SpreadedFire>().fireSourceName == this.name)
|
||
|
{
|
||
|
isSpreaded = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!isSpreaded)
|
||
|
{
|
||
|
index = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
index = 0;
|
||
|
}
|
||
|
|
||
|
if (fireAttri.isSpreadedBeforeRecord)
|
||
|
{
|
||
|
if (straightSpread)
|
||
|
{
|
||
|
isSpreading = true;
|
||
|
for (int i = 0; i < spreadFirePositions.Count; i++)
|
||
|
{
|
||
|
GameObject spreadFire = Instantiate(fire, spreadFirePositions[i], Quaternion.identity, GameObject.Find("AllParent").transform.Find("pfire")) as GameObject;
|
||
|
var spreadedFire = spreadFire.AddComponent<SpreadedFire>();
|
||
|
spreadedFire.fireSourceName = this.name;
|
||
|
}
|
||
|
isSpreading = false;
|
||
|
//flag = true;
|
||
|
}
|
||
|
|
||
|
if (areaSpread || aroundSpread)
|
||
|
{
|
||
|
isSpreading = true;
|
||
|
for (int i = 0; i < spdFirePositions.Count; i++)
|
||
|
{
|
||
|
for (int j = 0; j < spdFirePositions[i].Count; j++)
|
||
|
{
|
||
|
GameObject spreadFire = Instantiate(fire, spdFirePositions[i][j], Quaternion.identity, GameObject.Find("AllParent").transform.Find("pfire")) as GameObject;
|
||
|
var spreadedFire = spreadFire.AddComponent<SpreadedFire>();
|
||
|
spreadedFire.fireSourceName = this.name;
|
||
|
}
|
||
|
}
|
||
|
isSpreading = false;
|
||
|
//flag = true;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (!fireAttri.isStartSpread)
|
||
|
{
|
||
|
startWaitTime = DateTime.Now;
|
||
|
|
||
|
//StopCoroutine("WaitSenconds");
|
||
|
StopAllCoroutines();
|
||
|
|
||
|
if (changedSpeed != 0)
|
||
|
{
|
||
|
StartCoroutine(WaitSenconds(startTime * 60f / changedSpeed));
|
||
|
changedSpeed = 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//StartCoroutine(WaitSenconds(startTime * 60f));
|
||
|
|
||
|
if (LoadManager.Instance.IsPlayBacking)
|
||
|
{//回放时在还没实例化火前,播放速度就变了的情况(需要等待时间的情况)
|
||
|
spreadSpeed = 4.0f;
|
||
|
repeatRate = 4.0f;
|
||
|
spreadSpeed = spreadSpeed / LoadManager.Instance.LoadSpeed;
|
||
|
repeatRate = repeatRate / LoadManager.Instance.LoadSpeed;
|
||
|
|
||
|
StartCoroutine(WaitSenconds(startTime * 60f / LoadManager.Instance.LoadSpeed));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
StartCoroutine(WaitSenconds(startTime * 60f));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//StartCoroutine(WaitSenconds(startTime * 0f));
|
||
|
if (LoadManager.Instance.IsPlayBacking)
|
||
|
{//回放时在还没实例化火前,播放速度就变了的情况(不需要等待时间的情况)
|
||
|
spreadSpeed = 4.0f;
|
||
|
repeatRate = 4.0f;
|
||
|
spreadSpeed = spreadSpeed / LoadManager.Instance.LoadSpeed;
|
||
|
repeatRate = repeatRate / LoadManager.Instance.LoadSpeed;
|
||
|
|
||
|
StartCoroutine(WaitSenconds(startTime * 0f));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
StartCoroutine(WaitSenconds(startTime * 0f));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void Execute1(IMessage msg)
|
||
|
{
|
||
|
if ((string)msg.Sender == this.name)
|
||
|
{
|
||
|
Transform pfire = GameObject.Find("pfire").transform;
|
||
|
foreach (Transform child in pfire)
|
||
|
{
|
||
|
if (child.GetComponent<SpreadedFire>() && child.GetComponent<SpreadedFire>().fireSourceName == (string)msg.Sender)
|
||
|
{
|
||
|
Destroy(child.gameObject);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
index = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IEnumerator WaitSenconds(float delay)
|
||
|
{
|
||
|
yield return new WaitForSeconds(delay);
|
||
|
|
||
|
if (!(isSpreading || flag))//加载情况开始蔓延时,如果在等待时间到达之前手动按F5导致已经开始蔓延或导致蔓延已经完成,到达时间不触发蔓延
|
||
|
{
|
||
|
isSpreading = true;
|
||
|
|
||
|
//if (RecordManager.Instance.IsRecording)//记录火开始蔓延事件
|
||
|
//{
|
||
|
// MessageDispatcher.SendMessage("RecordFireStartSpreadEvent", (object)this.name);
|
||
|
//}
|
||
|
|
||
|
InvokeRepeating("CtrlFireSpread", spreadSpeed, repeatRate);
|
||
|
|
||
|
flag = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void CtrlFireSpread()
|
||
|
{
|
||
|
if (straightSpread)
|
||
|
{
|
||
|
if (index < spreadFirePositions.Count)
|
||
|
{
|
||
|
GameObject spreadFire = Instantiate(fire, spreadFirePositions[index++], Quaternion.identity, GameObject.Find("AllParent").transform.Find("pfire")) as GameObject;
|
||
|
//var spreadedFire = spreadFire.AddComponent<SpreadedFire>();
|
||
|
var spreadedFire = spreadFire.GetComponent<SpreadedFire>();
|
||
|
spreadedFire.fireSourceName = this.name;
|
||
|
spreadFire.GetComponent<CengID>().cengID = GetComponent<CengID>().cengID;//蔓延火添加CengID属性
|
||
|
spreadFire.GetComponent<CengID>().CengIDBuildType = GetComponent<CengID>().CengIDBuildType;
|
||
|
//spreadFire.name = "中队名" + "-" + "fire" + "-" + fire.name + "-" + this.name + "-0";
|
||
|
spreadFire.name = "中队名" + "-" + "fire" + "-" + "GroundFire_LG" + "-+" + this.name + "(Node)+-" + TrackRecordHelpClass.GetFileNameAccordingTime(DateTime.Now) + index;//避免名字重复,不然会重复记录实例化事件
|
||
|
if (RecordManager.Instance.IsRecording)//记录蔓延出来的火实例化的事件
|
||
|
{
|
||
|
MessageDispatcher.SendMessage("RecordInstantiateEvent", (object)spreadFire.name);
|
||
|
}
|
||
|
|
||
|
if (index == spreadFirePositions.Count)
|
||
|
{
|
||
|
CancelInvoke("CtrlFireSpread");
|
||
|
isSpreading = false;
|
||
|
//if (LoadManager.Instance.IsPlayBacking)
|
||
|
//{
|
||
|
// flag = false;
|
||
|
// spreadSpeed = 4.0f;
|
||
|
// repeatRate = 4.0f;
|
||
|
|
||
|
// TheBackView.instance.SpeedChangeEvent -= OnSpeedChangeEvent;
|
||
|
//}
|
||
|
|
||
|
this.GetComponent<ShowFireSetWin>().fireAttri.isSpreadedBeforeRecord = true;
|
||
|
|
||
|
if (ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CreatQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CopyQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.PrepareMode
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditCourceware
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.SelfStudyMode)
|
||
|
{
|
||
|
if (RecordManager.Instance.IsRecording
|
||
|
|| (!RecordManager.Instance.IsRecording && !LoadManager.Instance.IsPlayBacking))
|
||
|
{
|
||
|
messageBox.GetComponent<MessageTool>().showMessage(ShowMessageType.prompt, "提示信息", "蔓延已完成");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (areaSpread || aroundSpread)
|
||
|
{
|
||
|
if (index < spdFirePositions.Count)
|
||
|
{
|
||
|
List<Vector3> tempFirePosList = spdFirePositions[index++];
|
||
|
for (int j = 0; j < tempFirePosList.Count; j++)
|
||
|
{
|
||
|
GameObject spreadFire = Instantiate(fire, tempFirePosList[j], Quaternion.identity, GameObject.Find("AllParent").transform.Find("pfire")) as GameObject;
|
||
|
//var spreadedFire = spreadFire.AddComponent<SpreadedFire>();
|
||
|
var spreadedFire = spreadFire.GetComponent<SpreadedFire>();
|
||
|
spreadedFire.fireSourceName = this.name;
|
||
|
spreadFire.GetComponent<CengID>().cengID = GetComponent<CengID>().cengID;//蔓延火添加CengID属性
|
||
|
spreadFire.GetComponent<CengID>().CengIDBuildType = GetComponent<CengID>().CengIDBuildType;
|
||
|
//spreadFire.name = "中队名" + "-" + "fire" + "-" + fire.name + "-" + this.name + "-0";
|
||
|
spreadFire.name = "中队名" + "-" + "fire" + "-" + "GroundFire_LG" + "-+" + this.name + "(Node)+-" + TrackRecordHelpClass.GetFileNameAccordingTime(DateTime.Now) + index + "-" + j;//避免名字重复,不然会重复记录实例化事件
|
||
|
if (RecordManager.Instance.IsRecording)//记录蔓延出来的火实例化的事件
|
||
|
{
|
||
|
MessageDispatcher.SendMessage("RecordInstantiateEvent", (object)spreadFire.name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (index == spdFirePositions.Count)
|
||
|
{
|
||
|
CancelInvoke("CtrlFireSpread");
|
||
|
isSpreading = false;
|
||
|
//if (LoadManager.Instance.IsPlayBacking)
|
||
|
//{
|
||
|
// flag = false;
|
||
|
// spreadSpeed = 4.0f;
|
||
|
// repeatRate = 4.0f;
|
||
|
|
||
|
// TheBackView.instance.SpeedChangeEvent -= OnSpeedChangeEvent;
|
||
|
//}
|
||
|
|
||
|
this.GetComponent<ShowFireSetWin>().fireAttri.isSpreadedBeforeRecord = true;
|
||
|
|
||
|
if (ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CreatQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CopyQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.PrepareMode
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditCourceware
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.SelfStudyMode)
|
||
|
{
|
||
|
if (RecordManager.Instance.IsRecording
|
||
|
|| (!RecordManager.Instance.IsRecording && !LoadManager.Instance.IsPlayBacking))
|
||
|
{
|
||
|
messageBox.GetComponent<MessageTool>().showMessage(ShowMessageType.prompt, "提示信息", "蔓延已完成");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void GetSpreadFirePositions()
|
||
|
{
|
||
|
//获取蔓延路径上需要克隆火的位置
|
||
|
if (straightSpread)
|
||
|
{
|
||
|
spreadFirePositions.Clear();
|
||
|
|
||
|
for (int i = 0; i < pathPointList.Count; i++)
|
||
|
{
|
||
|
if ((i + 1) <= (pathPointList.Count - 1))
|
||
|
{
|
||
|
distance = Vector3.Distance(pathPointList[i], pathPointList[i + 1]);
|
||
|
|
||
|
result = (int)(distance / spreadDis);
|
||
|
|
||
|
for (int j = 1; j <= result; j++)
|
||
|
{
|
||
|
spreadFirePositions.Add(Vector3.MoveTowards(pathPointList[i], pathPointList[i + 1], spreadDis * j));
|
||
|
}
|
||
|
|
||
|
spreadFirePositions.Add(pathPointList[i + 1]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (areaSpread || aroundSpread)
|
||
|
{
|
||
|
//找出多边形xz平面包围盒
|
||
|
float[] polyline = new float[2 * pathPointList.Count];
|
||
|
for (int i = 0; i < pathPointList.Count; i++)
|
||
|
{
|
||
|
polyline[i + i] = pathPointList[i].x;
|
||
|
polyline[i + i + 1] = pathPointList[i].z;
|
||
|
}
|
||
|
|
||
|
float maxx = 0, minx = 0, maxz = 0, minz = 0;
|
||
|
int pointcount = 0;
|
||
|
if (polyline != null)
|
||
|
{
|
||
|
pointcount = polyline.Length / 2;
|
||
|
maxx = minx = polyline[0];
|
||
|
maxz = minz = polyline[1];
|
||
|
for (int i = 0; i < pointcount; i++)
|
||
|
{
|
||
|
if (maxx < polyline[i + i])
|
||
|
maxx = polyline[i + i];
|
||
|
if (minx > polyline[i + i])
|
||
|
minx = polyline[i + i];
|
||
|
if (maxz < polyline[i + i + 1])
|
||
|
maxz = polyline[i + i + 1];
|
||
|
if (minz > polyline[i + i + 1])
|
||
|
minz = polyline[i + i + 1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int count_z = (int)((maxz - minz) / spreadDis);
|
||
|
int count_x = (int)((maxx - minx) / spreadDis);
|
||
|
List<Vector2> temp = new List<Vector2>();//包围盒内按spreadDis等距分割的所有点
|
||
|
for (int i = 0; i <= count_x; i++)
|
||
|
{
|
||
|
for (int j = 0; j <= count_z; j++)
|
||
|
{
|
||
|
temp.Add(new Vector2(minx + spreadDis * i, minz + spreadDis * j));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
List<Vector2> pathPointList_xz = new List<Vector2>();//xz平面多边形
|
||
|
for (int i = 0; i < pathPointList.Count; i++)
|
||
|
{
|
||
|
pathPointList_xz.Add(new Vector2(pathPointList[i].x, pathPointList[i].z));
|
||
|
}
|
||
|
List<Vector2> spreadFirePositions_xz = new List<Vector2>();//xz平面多边形内部的点
|
||
|
for (int i = 0; i < temp.Count; i++)
|
||
|
{
|
||
|
int wn = wn_PnPoly(pathPointList_xz, temp[i]);
|
||
|
if (wn != 0)
|
||
|
{
|
||
|
spreadFirePositions_xz.Add(new Vector3(temp[i].x, temp[i].y));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//分批次构建火点数据结构
|
||
|
Vector2 firePos_xz = new Vector2(this.transform.position.x, this.transform.position.z);
|
||
|
float maxFanWei = Vector2.Distance(temp[0], temp[temp.Count - 1]);
|
||
|
int pici = (int)(maxFanWei / spreadDis);//蔓延批次
|
||
|
pici = pici + 1;
|
||
|
|
||
|
spdFirePositions.Clear();
|
||
|
|
||
|
for (int i = 1; i <= pici; i++)
|
||
|
{
|
||
|
List<Vector2> tempList1 = new List<Vector2>();
|
||
|
List<Vector3> tempList = new List<Vector3>();
|
||
|
for (int j = 0; j < spreadFirePositions_xz.Count; j++)
|
||
|
{
|
||
|
float dis = Vector2.Distance(firePos_xz, spreadFirePositions_xz[j]);
|
||
|
if (dis != 0 && dis <= i * spreadDis)
|
||
|
{
|
||
|
tempList1.Add(spreadFirePositions_xz[j]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (int n = 0; n < tempList1.Count; n++)
|
||
|
{
|
||
|
tempList.Add(new Vector3(tempList1[n].x, this.transform.position.y, tempList1[n].y));
|
||
|
}
|
||
|
|
||
|
spdFirePositions.Add(tempList);
|
||
|
|
||
|
for (int m = 0; m < tempList1.Count; m++)
|
||
|
{
|
||
|
if (spreadFirePositions_xz.Contains(tempList1[m]))
|
||
|
{
|
||
|
spreadFirePositions_xz.Remove(tempList1[m]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//因为批次是按包围盒最大点到最小点的距离除以一个批次的蔓延距离,所以可能出现没有点的批次,需要去除
|
||
|
for (int i = spdFirePositions.Count - 1; i >= 0; i--)
|
||
|
{
|
||
|
if (spdFirePositions[i].Count == 0)
|
||
|
{
|
||
|
spdFirePositions.RemoveAt(i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void OnDestroy()
|
||
|
{
|
||
|
MessageDispatcher.RemoveListener("SETFIRE", Execute);
|
||
|
TheBackView.instance.SpeedChangeEvent -= OnSpeedChangeEvent;
|
||
|
MessageDispatcher.RemoveListener("RESETFIRE", Execute1);
|
||
|
MessageDispatcher.RemoveListener("REGISTERSPEEDCHANGEEVENT", RegisterSpeedChangeEvent);
|
||
|
|
||
|
StopAllCoroutines();
|
||
|
|
||
|
MessageDispatcher.RemoveListener("TriggerFireSpread", TriggerFireSpread);
|
||
|
}
|
||
|
|
||
|
private void TriggerFireSpread(IMessage msg)
|
||
|
{
|
||
|
if ((string)msg.Sender == this.name)
|
||
|
{
|
||
|
int count = (int)msg.Data;
|
||
|
|
||
|
//各种加载的情况下控制火的蔓延
|
||
|
fireAttri = this.GetComponent<ShowFireSetWin>().fireAttri;
|
||
|
|
||
|
if (!isSpreading)
|
||
|
{
|
||
|
if (fireAttri.PathPointList.Count > 0)
|
||
|
{
|
||
|
if (!flag)
|
||
|
{
|
||
|
straightSpread = fireAttri.StraightSpread;
|
||
|
areaSpread = fireAttri.AreaSpread;
|
||
|
aroundSpread = fireAttri.AroundSpread;
|
||
|
startTime = fireAttri.StartTime;
|
||
|
pathPointList = fireAttri.PathPointList;
|
||
|
|
||
|
if (pathPointList.Count > 0)
|
||
|
GetSpreadFirePositions();//获取火蔓延生成火的所有位置
|
||
|
|
||
|
if (!(ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CopyQuestion))
|
||
|
{
|
||
|
if (straightSpread || areaSpread || aroundSpread)
|
||
|
{
|
||
|
Transform pfire = GameObject.Find("pfire").transform;
|
||
|
if (straightSpread)
|
||
|
{
|
||
|
bool isSpreaded = false;
|
||
|
//控制index,以控制蔓延过火后重新设置路径(接着以前路径增加)后,接着蔓延;
|
||
|
//若是换蔓延方式或者重置路径后再重新设置路径,则从头开始蔓延
|
||
|
foreach (Transform child in pfire)
|
||
|
{
|
||
|
if (child.GetComponent<SpreadedFire>() && child.GetComponent<SpreadedFire>().fireSourceName == this.name)
|
||
|
{
|
||
|
isSpreaded = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!isSpreaded)
|
||
|
{
|
||
|
index = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
index = 0;
|
||
|
}
|
||
|
|
||
|
if (count == 0)
|
||
|
{
|
||
|
StartCoroutine(WaitSenconds(startTime * 60f));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (straightSpread)
|
||
|
{
|
||
|
if (count < spreadFirePositions.Count)
|
||
|
{
|
||
|
index = count;
|
||
|
StartCoroutine(WaitSenconds(startTime * 0f));
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int ct = 0;
|
||
|
for (int i = 0; i < spdFirePositions.Count; i++)
|
||
|
{
|
||
|
List<Vector3> tempFirePosList = spdFirePositions[i];
|
||
|
ct += tempFirePosList.Count;
|
||
|
if (count == ct)
|
||
|
{
|
||
|
index = i + 1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (index < spdFirePositions.Count)
|
||
|
{
|
||
|
StartCoroutine(WaitSenconds(startTime * 0f));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 判断点是否在多边形内
|
||
|
/// </summary>
|
||
|
/// <param name="pathPointList">多边形顶点数组</param>
|
||
|
/// <param name="point">多边形包围盒内按spreadDis等距分割的各点</param>
|
||
|
/// <returns></returns>
|
||
|
// wn_PnPoly(): winding number test for a point in a polygon
|
||
|
// Input: point = a point,
|
||
|
// polygon = anticlockwise vertex points of a polygon polygon[n]
|
||
|
// Return: wn = the winding number (=0 only when P is outside)
|
||
|
// See:"http://geomalgorithms.com/a03-_inclusion.html"
|
||
|
int wn_PnPoly(List<Vector2> pathPointList, Vector2 point)
|
||
|
{
|
||
|
int n = pathPointList.Count;
|
||
|
int wn = 0; // the winding number counter
|
||
|
|
||
|
// loop through all edges of the polygon
|
||
|
for (int i = 0; i < n; i++)
|
||
|
{ // edge from polygon[i] to polygon[i+1]
|
||
|
if (pathPointList[i].y <= point.y)
|
||
|
{ // start y <= P.y
|
||
|
if (pathPointList[(i + 1) % n].y > point.y) // an upward crossing
|
||
|
if (isLeft(pathPointList[i], pathPointList[(i + 1) % n], point) > 0) // P left of edge
|
||
|
++wn; // have a valid up intersect
|
||
|
}
|
||
|
else
|
||
|
{ // start y > P.y (no test needed)
|
||
|
if (pathPointList[(i + 1) % n].y <= point.y) // a downward crossing
|
||
|
if (isLeft(pathPointList[i], pathPointList[(i + 1) % n], point) < 0) // P right of edge
|
||
|
--wn; // have a valid down intersect
|
||
|
}
|
||
|
}
|
||
|
return wn;
|
||
|
}
|
||
|
|
||
|
//isLeft(): tests if a point is Left|On|Right of an infinite line.
|
||
|
//Input: three points P0, P1, and P2
|
||
|
//Return: >0 for P2 left of the line through P0 and P1
|
||
|
// =0 for P2 on the line
|
||
|
// <0 for P2 right of the line
|
||
|
// See:"http://geomalgorithms.com/a03-_inclusion.html":Algorithm 1 "Area of Triangles and Polygons"
|
||
|
// Or "http://geomalgorithms.com/a01-_area.html"
|
||
|
float isLeft(Vector2 P0, Vector2 P1, Vector2 P2)
|
||
|
{
|
||
|
return ((P1.x - P0.x) * (P2.y - P0.y)
|
||
|
- (P2.x - P0.x) * (P1.y - P0.y));
|
||
|
}
|
||
|
|
||
|
// Update is called once per frame
|
||
|
void Update()
|
||
|
{
|
||
|
//各种能设置火灾情蔓延的情况,设置好后火蔓延的控制
|
||
|
|
||
|
//创建考题,备课中新建课件,自学
|
||
|
if (ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CreatQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.CopyQuestion
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.PrepareMode
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.EditCourceware
|
||
|
|| ExamInfoHelpClass.loadSceneMode == ExamInfoHelpClass.LoadSceneMode.SelfStudyMode)
|
||
|
{
|
||
|
//新建节点,既没有新建节点也没有加载节点两种情况下允许按F5设置开始蔓延(加载节点不允许按F5设置开始蔓延)
|
||
|
if (RecordManager.Instance.IsRecording
|
||
|
|| (!RecordManager.Instance.IsRecording && !LoadManager.Instance.IsPlayBacking))
|
||
|
{
|
||
|
|
||
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||
|
|
||
|
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
|
||
|
{
|
||
|
if (hit.transform.name == this.name)
|
||
|
{
|
||
|
if (Input.GetKeyDown(KeyCode.F5))
|
||
|
{
|
||
|
if (!isSpreading)
|
||
|
{
|
||
|
if (!flag)
|
||
|
{
|
||
|
if (!this.GetComponent<ShowFireSetWin>().fireAttri.StraightSpread
|
||
|
&& !this.GetComponent<ShowFireSetWin>().fireAttri.AreaSpread
|
||
|
&& !this.GetComponent<ShowFireSetWin>().fireAttri.AroundSpread)
|
||
|
{
|
||
|
messageBox.GetComponent<MessageTool>().showMessage(ShowMessageType.prompt, "提示信息", "还没有设置火的蔓延方式");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
FireInfoImage.SetActive(false);
|
||
|
|
||
|
ConfirmFireSpreadWin.SetActive(true);
|
||
|
ConfirmFireSpreadWin.transform.Find("ConfirmButton").GetComponent<ConfirmSpread>().fire = this.gameObject;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
messageBox.GetComponent<MessageTool>().showMessage(ShowMessageType.prompt, "提示信息", "已经蔓延完成了");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
messageBox.GetComponent<MessageTool>().showMessage(ShowMessageType.prompt, "提示信息", "已经开始蔓延");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (isSpreading)
|
||
|
{
|
||
|
fireAttri = this.GetComponent<ShowFireSetWin>().fireAttri;
|
||
|
if (fireAttri.PathPointList.Count > 0)
|
||
|
{
|
||
|
if (!flag)
|
||
|
{
|
||
|
straightSpread = fireAttri.StraightSpread;
|
||
|
areaSpread = fireAttri.AreaSpread;
|
||
|
aroundSpread = fireAttri.AroundSpread;
|
||
|
startTime = fireAttri.StartTime;
|
||
|
pathPointList = fireAttri.PathPointList;
|
||
|
|
||
|
GetSpreadFirePositions();//获取火蔓延生成火的所有位置
|
||
|
|
||
|
if (straightSpread || areaSpread || aroundSpread)
|
||
|
{
|
||
|
Transform pfire = GameObject.Find("pfire").transform;
|
||
|
if (straightSpread)
|
||
|
{
|
||
|
bool isSpreaded = false;
|
||
|
//控制index,以控制蔓延过火后重新设置路径(接着以前路径增加)后,接着蔓延;
|
||
|
//若是换蔓延方式或者重置路径后再重新设置路径,则从头开始蔓延
|
||
|
foreach (Transform child in pfire)
|
||
|
{
|
||
|
if (child.GetComponent<SpreadedFire>() && child.GetComponent<SpreadedFire>().fireSourceName == this.name)
|
||
|
{
|
||
|
isSpreaded = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!isSpreaded)
|
||
|
{
|
||
|
index = 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
index = 0;
|
||
|
|
||
|
foreach (Transform child in pfire)
|
||
|
{
|
||
|
if (child.GetComponent<SpreadedFire>() && child.GetComponent<SpreadedFire>().fireSourceName == this.name)
|
||
|
{
|
||
|
Destroy(child.gameObject);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//if (RecordManager.Instance.IsRecording)//记录火开始蔓延事件
|
||
|
//{
|
||
|
// MessageDispatcher.SendMessage("RecordFireStartSpreadEvent", (object)this.name);
|
||
|
//}
|
||
|
|
||
|
InvokeRepeating("CtrlFireSpread", spreadSpeed, repeatRate);
|
||
|
}
|
||
|
|
||
|
flag = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|