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.
403 lines
14 KiB
403 lines
14 KiB
using UnityEngine; |
|
using System.Collections; |
|
using System; |
|
using AX.TrackRecord; |
|
using AX.MessageSystem; |
|
using UnityEngine.AI; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
|
|
public class AgentControl : MonoBehaviour |
|
{ |
|
|
|
private UnityEngine.AI.NavMeshAgent agent; |
|
public UnityEngine.AI.NavMeshPath NavMeshPath; |
|
private UnityEngine.AI.NavMeshObstacle obstacle;//寻路障碍 |
|
public Vector3 point; |
|
public int cengNum; |
|
public BuildType buildType; |
|
private RaycastHit hit; |
|
DateTime t1, t2; |
|
public bool toshinei; |
|
|
|
[HideInInspector] |
|
public int lastMask = 0; |
|
|
|
/// <summary>寻路过程中的拐点</summary> |
|
public Vector3[] nowpath; |
|
|
|
// private bool IsFirstPFFlag = false;//该记录的第一次寻路标志,开始记录时赋值true |
|
|
|
|
|
void Awake() |
|
{ |
|
pathfindingLayer = 1 << 25 | 1 << 26| 1 << 31; |
|
agent = GetComponent<UnityEngine.AI.NavMeshAgent>(); |
|
agent.acceleration = 50000000; |
|
NavMeshPath = new UnityEngine.AI.NavMeshPath(); |
|
lastMask = GetComponent<UnityEngine.AI.NavMeshAgent>().areaMask; |
|
if (this.transform.parent.gameObject.name == "pxiaofangche") |
|
agent.speed = 7f * 3f; |
|
else |
|
{ |
|
agent.speed = 3.5f * 3f; |
|
} |
|
if (GetComponent<UnityEngine.AI.NavMeshObstacle>()) |
|
{//如果 有障碍组件,就添加切换脚本,如果没有,跳过即可---------------此处在消防车加上NavmeshObstacle后需要修改 |
|
obstacle = GetComponent<UnityEngine.AI.NavMeshObstacle>(); |
|
agent.enabled = false; |
|
obstacle.enabled = true; |
|
gameObject.AddComponent<AgentSwitch>(); |
|
} |
|
else |
|
{ |
|
agent.enabled = true; |
|
} |
|
|
|
gameObject.AddComponent<AgentRecord>(); |
|
|
|
|
|
} |
|
|
|
public void Setpath(Vector3[] path) |
|
{ |
|
nowpath = path; |
|
} |
|
void Update() |
|
{ |
|
//寻路:初始速度;恒定,以此记录寻路时间 |
|
//回放:时间恒定,对应的目的点一样,以此计算出寻路速度; |
|
|
|
if (Input.GetMouseButtonDown(1)) |
|
{ |
|
t2 = DateTime.Now; |
|
if (t2 - t1 > new TimeSpan(0, 0, 0, 0, 249)) |
|
{//不是要寻路的双击,没必要切换这些乱七八糟的 |
|
t1 = t2; |
|
return; |
|
} |
|
|
|
if (!TrackRecordHelpClass.CheckIfCanControl()) |
|
{ |
|
return; |
|
} |
|
|
|
if (GetComponent<LineamentEvent>().isConnectCar && name.Contains("xiaofangche")) |
|
{ |
|
MessageDispatcher.SendMessage("Operatinghints", (object)"请收起消防管线再移动消防车"); |
|
return; |
|
} |
|
|
|
if (obstacle) |
|
{//obstacle这货存在时的寻路方式 |
|
StartCoroutine(delayActive()); |
|
} |
|
else |
|
{ |
|
//obstacle 不存在时 的寻路方式 |
|
FindingPath(); |
|
} |
|
|
|
} |
|
} |
|
|
|
public void SetNearestXfy(Vector3[] points,int startID) |
|
{ |
|
if (points.Length > 1) |
|
{ |
|
var targetPoint = points[startID + 1]; |
|
var xfyList = InputManager.Instance_.GetSelectedCharacters(); |
|
float min = 10000; |
|
int index = 0; |
|
|
|
for (int i = 0; i < xfyList.Count; i++) |
|
{ |
|
var distance = Vector3.Distance(targetPoint, xfyList[i].transform.position); |
|
if (distance < min) |
|
{ |
|
min = distance; |
|
index = i; |
|
} |
|
} |
|
//foreach(Transform xfy in GameObject.Find("pxiaofangyuan").transform) |
|
//{ |
|
// xfy.GetComponent<AgentRecord>().canRecordPathFinding = false; |
|
//} |
|
xfyList[index].GetComponent<AgentRecord>().theNearestXFY = true; |
|
} |
|
|
|
|
|
} |
|
|
|
private string GetXFYName(Vector3 navTo) |
|
{ |
|
var xfyList = InputManager.Instance_.GetSelectedCharacters(); |
|
int index = -1; |
|
float near = 100; |
|
for (int i = 0; i < xfyList.Count; i++) |
|
{ |
|
var distance = Vector3.Distance(navTo, xfyList[i].transform.position); |
|
if (distance < near) |
|
{ |
|
near = distance; |
|
index = i; |
|
} |
|
} |
|
return xfyList[index].name; |
|
} |
|
|
|
private void setXiaoFangYuan() |
|
{ |
|
int curMask = 0; |
|
setCengNum(hit.transform.gameObject); |
|
if (GetComponent<CengID>().cengID == 0 && cengNum == 0)//判断是否只在室外寻路,防止从室内抄近路 |
|
{ |
|
//GetComponent<NavMeshAgent>().areaMask = 24; |
|
//curMask = 24; |
|
} |
|
else |
|
{ |
|
//GetComponent<NavMeshAgent>().areaMask = 25; |
|
//curMask = 25; |
|
} |
|
if (GetComponent<CengID>().cengID == 0 && cengNum != 0)//判断是否由室外进入室内 |
|
{ |
|
toshinei = GetComponent<XiaoFangYuanToShiNei>().toShiNei(); |
|
} |
|
else |
|
{ |
|
toshinei = true; |
|
} |
|
//toOtherCeng = GetComponent<XiaoFangYuanToShiNei>().toOtherCeng(cengNum); |
|
|
|
|
|
if (RecordManager.Instance.IsRecording) |
|
{ |
|
if (lastMask != curMask) |
|
{ |
|
lastMask = curMask; |
|
MessageDispatcher.SendMessage((object)name, "RECORDMASKCHANGEEVENT"); |
|
} |
|
} |
|
|
|
} |
|
private void setCengNum(GameObject obj) |
|
{ |
|
//if (obj.transform.parent) |
|
//{ |
|
// GameObject pobj = obj.transform.parent.gameObject; |
|
// if (obj.tag == "nei") |
|
// { |
|
// string hitName = obj.name; |
|
// cengNum = int.Parse(hitName.Substring(3)); |
|
// return; |
|
// } |
|
// else |
|
// { |
|
// cengNum = 0; |
|
// } |
|
// setCengNum(pobj); |
|
//} |
|
if (obj.GetComponent<CengID>()) |
|
{ |
|
cengNum = obj.GetComponent<CengID>().cengID; |
|
buildType = obj.GetComponent<CengID>().CengIDBuildType; |
|
|
|
//MessageDispatcher.SendMessage(this.name, "SetCengID", build); |
|
} |
|
} |
|
|
|
|
|
/// <summary> |
|
/// 延迟激活NavmeshAgent,因其同时与NavmeshObstacle激活会出现位置的短位移 |
|
/// </summary> |
|
/// <returns></returns> |
|
IEnumerator delayActive() |
|
{ |
|
obstacle.enabled = false; |
|
yield return null; |
|
|
|
if (!obstacle.enabled) |
|
{ |
|
FindingPath(); |
|
} |
|
else |
|
{ |
|
StartCoroutine(delayActive()); |
|
} |
|
} |
|
|
|
LayerMask pathfindingLayer = 1 << 25 | 1 << 26; |
|
|
|
float GetF1(float f) |
|
{ |
|
float f1 = Mathf.Abs(f); |
|
int fi = (int)(f1 * 10); |
|
f1 = (float)(fi / 10.0f); |
|
return f1;//* (f < 0 ? -1 : 1) |
|
} |
|
void FindingPath() |
|
{ |
|
t1 = t2; |
|
|
|
agent.enabled = true; |
|
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); |
|
//the mouse ray has hit a collider in the scene |
|
if (Physics.Raycast(ray, out hit, Mathf.Infinity, pathfindingLayer)) |
|
{ |
|
NavMeshPath.ClearCorners(); |
|
try |
|
{ |
|
UnityEngine.AI.NavMesh.CalculatePath(transform.position, hit.point, GetComponent<UnityEngine.AI.NavMeshAgent>().areaMask, NavMeshPath); |
|
} |
|
catch (Exception e) |
|
{ |
|
System.Diagnostics.Trace.TraceError(e.Message); |
|
} |
|
NavMeshPath np = new NavMeshPath(); |
|
UnityEngine.AI.NavMesh.CalculatePath(transform.position, transform.position, GetComponent<UnityEngine.AI.NavMeshAgent>().areaMask, np); |
|
bool flag = np.corners.Length > 0 ? true : false; |
|
//Debug.Log(np.corners.Length); |
|
if (np.corners.Length == 0)//物体本身处于自己不能寻路的地方 |
|
{ |
|
MessageDispatcher.SendMessage("Operatinghints", (object)"该类型物体在此区域无法寻路!"); |
|
return; |
|
} |
|
if (gameObject.name.Contains("xiaofangche") && hit.collider.gameObject.layer == 26) |
|
{ |
|
MessageDispatcher.SendMessage("Operatinghints", (object)"该类型物体无法到达目的地!"); |
|
return; |
|
} |
|
|
|
if (tag == "Player")//如果是消防员 |
|
{ |
|
GetComponent<XiaoFangYuanDrawLine>().setLine(); |
|
setXiaoFangYuan(); |
|
toshinei = GetComponent<XiaoFangYuanToShiNei>().toShiNei();//直接执行该方法,使得室外也会消耗管线 |
|
if (toshinei) |
|
{ |
|
//if (GetComponent<NavMeshAgent>().areaMask == 25) |
|
//{ |
|
//任务是铺设管线或者照明线相关 |
|
if (TrackRecordHelpClass.IsCanDrawLine(GetComponent<ObjMessage>().TaskName)) |
|
{ |
|
GetComponent<XiaoFangYuanDrawLine>().setPath(NavMeshPath.corners);//将新的寻路关键点传给画线脚本 |
|
} |
|
GetComponent<AgentRecord>().nowpath = NavMeshPath.corners;//将新的寻路关键点传给记录脚本 |
|
|
|
///////////////////// |
|
//SetNearestXfy(NavMeshPath.corners, 0); |
|
//Vector3 newPoint = new Vector3(hit.point.x, hit.point.y + 1f, hit.point.z); |
|
if (GetComponent<CengID>()) |
|
{ |
|
GetComponent<AgentRecord>().SetList(); |
|
GetComponent<AgentRecord>().StartGo_(hit.transform.gameObject); |
|
} |
|
Transform Trager = GameObject.Find("target").transform; |
|
if (Trager.transform.parent != null) |
|
{ |
|
Trager.transform.localPosition = new Vector3(0, 4.36f, 0); |
|
} |
|
if (transform.Find("Bip01/Bip01 Pelvis/Bip01 Spine/shuiqiang").gameObject.activeInHierarchy) |
|
{//如果水枪被激活, |
|
if (!GetComponent<XiaoFangYuanDrawLine>().HasLine()) |
|
{//并且没有拿消防水带和照明线,不能寻路 |
|
MessageDispatcher.SendMessage("Operatinghints", (object)"请装备管线或停止灭火再移动"); |
|
InputManager.Instance_.removeItem(gameObject);//将其从框选中删除 |
|
return; |
|
} |
|
} |
|
else |
|
{ |
|
GetComponent<RLineControl>().LineList_GameObject.Clear();//消防员跑离管线,清除身上已有管线数组,若要出水,需要重新连接管线 |
|
} |
|
if (GetComponent<ObjMessage>().TaskName.Contains("铺设照明线")) |
|
{ |
|
if (!GetComponent<XiaoFangYuanDrawLine>().HasLine()) |
|
{ |
|
//没有拿照明线,不能寻路铺设照明线 |
|
MessageDispatcher.SendMessage("Operatinghints", (object)"请装备照明线后铺设"); |
|
InputManager.Instance_.removeItem(gameObject);//将其从框选中删除 |
|
return; |
|
} |
|
} |
|
|
|
|
|
try |
|
{ |
|
agent.SetDestination(hit.point); |
|
} |
|
catch(Exception e) |
|
{ |
|
Debug.Log(e); |
|
MessageDispatcher.SendMessage("Operatinghints", (object)"目的地无法寻路到达!"); |
|
} |
|
|
|
} |
|
} |
|
else |
|
{ |
|
|
|
|
|
GetComponent<CarAnimatorControl>().nowpath = NavMeshPath.corners /*agent.path.corners*/; //传递寻路拐点数组 |
|
GetComponent<CarAnimatorControl>().pathIndex = 0;//重置数组索引 |
|
|
|
GetComponent<AgentRecord>().nowpath = NavMeshPath.corners; |
|
if (GetComponent<CengID>()) |
|
{ |
|
GetComponent<AgentRecord>().StartGo_(hit.transform.gameObject); |
|
} |
|
try |
|
{ |
|
agent.SetDestination(hit.point); |
|
} |
|
catch (Exception e) |
|
{ |
|
Debug.Log(e); |
|
MessageDispatcher.SendMessage("Operatinghints", (object)"目的地无法寻路到达!"); |
|
} |
|
|
|
} |
|
} |
|
} |
|
|
|
|
|
public void delayNav(UnityEngine.AI.NavMeshPath navMeshPath, EventRecordItem_two eventItem) |
|
{ |
|
if (obstacle) |
|
{ |
|
StartCoroutine(delay(navMeshPath, eventItem)); |
|
} |
|
else |
|
{ |
|
agent.enabled = true; |
|
Setpath(navMeshPath.corners);//将新的寻路关键点传给寻路脚本 |
|
agent.SetDestination(eventItem.Navto); |
|
gameObject.GetComponent<CarAnimatorControl>().nowpath = navMeshPath.corners /*agent.path.corners*/; //传递寻路拐点数组 |
|
gameObject.GetComponent<CarAnimatorControl>().pathIndex = 0;//重置数组索引 |
|
} |
|
} |
|
|
|
IEnumerator delay(UnityEngine.AI.NavMeshPath navMeshPath, EventRecordItem_two eventItem) |
|
{ |
|
obstacle.enabled = false; |
|
yield return null; |
|
|
|
if (!obstacle.enabled) |
|
{ |
|
agent.enabled = true; |
|
Setpath(navMeshPath.corners);//将新的寻路关键点传给寻路脚本 |
|
agent.SetDestination(eventItem.Navto); |
|
gameObject.GetComponent<CarAnimatorControl>().nowpath = navMeshPath.corners /*agent.path.corners*/; //传递寻路拐点数组 |
|
gameObject.GetComponent<CarAnimatorControl>().pathIndex = 0;//重置数组索引 |
|
|
|
} |
|
else |
|
{ |
|
StartCoroutine(delay(navMeshPath, eventItem)); |
|
} |
|
} |
|
|
|
|
|
|
|
}
|
|
|