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.
404 lines
14 KiB
404 lines
14 KiB
3 years ago
|
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));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|