using AX.MessageSystem; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using System; using AX.InputSystem; using AX.NetworkSystem; public class TrappedPathFind : MonoBehaviour { private NavMeshAgent agent; private NavMeshPath NavMeshPath; private NavMeshQueryFilter filter; private Vector3 pointhit;//寻路点 private GameObject hitObj;//寻路的对象 public List corners = new List(); private Vector3 lastPosition; public bool pathFindEnable; private NavMeshPath path; /// /// 是否被引导 /// private bool guidance; private CloneGameObjInfo gameobjinfo; void Start() { pathFindEnable = true; NavMeshPath = new NavMeshPath(); agent = GetComponent(); filter = new NavMeshQueryFilter(); filter.agentTypeID = agent.agentTypeID; filter.areaMask = agent.areaMask; path = new NavMeshPath(); gameobjinfo = GetComponent(); } void OnEnable() { MessageDispatcher.AddListener("TRAPPED_PATH_FINDING_COMMAND", PathFinding); } void OnDisable() { MessageDispatcher.RemoveListener("TRAPPED_PATH_FINDING_COMMAND", PathFinding); } void OnDestroy() { MessageDispatcher.RemoveListener("TRAPPED_PATH_FINDING_COMMAND", PathFinding); } private void Update() { if (Vector3.Distance(transform.position, pointhit) < 0.5f) { AdjustRotationWhileEndPathfindData arg = new AdjustRotationWhileEndPathfindData { SenderId = CurrentUserInfo.mySelf.Id, GameObjId = gameobjinfo.gameObjID, Hitpoint = pointhit, EndRotation = new Vector3(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, transform.rotation.eulerAngles.z) }; NetworkManager.Default.SendAsync("ABJUST_ROTATION_SYNC", arg); } } private void PathFinding(IMessage obj) { if (pathFindEnable) { var data = (TrappedPathFindingCmdArgs)obj.Data; //GameObject fireman = data.fireman; pointhit = data.hitPoint; // GetComponent().targetPosition = pointhit; //long gameID = data.gameObjID; long selfID = data.gameObjIdSelf; // List movelist = data.MoveIdlist; //自由状态 if (selfID != 0) { if (selfID == GetComponent().gameObjID) { GetComponent().TargetPosition = pointhit; StopAllCoroutines(); //StopCoroutine("GoToDestination"); corners.Clear(); bool flag = setPathCorners(transform.position, pointhit, corners); if (flag) { //hitObj = EntitiesManager.Instance.GetEntityByID(data.gameObjID); removeNoMainCorners(corners); if (agent.enabled == true) { StartCoroutine(GoToDestination(data)); } //寻路同步 // if (!GetComponent().Guidance) { PathFindSyncData pathsync = new PathFindSyncData(); pathsync.SendUserID = CurrentUserInfo.mySelf.Id; pathsync.TargetPoint = data.hitPoint; pathsync.TrappedMeetDangerous = data.MeetDangerous; pathsync.gameObjID = GetComponent().gameObjID; pathsync.gameObjType = GetComponent().gameObjType; pathsync.UserID = GetComponent().UserID; pathsync.trappedTargetpoint = pointhit; NetworkManager.Default.SendAsync(/*CurrentUserInfo.mySelf.Id,*/ "PATHFIND_SYNC", pathsync); } } else { if(GetComponent().Guidance) { LoadPromptWin.Instance.LoadTextPromptWindow("被困人员无法到达下一个引导点", 1f); } } } } ////被移动状态 //else //{ // if (movelist.Count > 0 && GetComponent().MoveFireman == fireman) // { // if (movelist.Contains(GetComponent().gameObjID)) // { // GetComponent().targetPosition = pointhit; // StopAllCoroutines(); // //StopCoroutine("GoToDestination"); // corners.Clear(); // bool flag = setPathCorners(transform.position, pointhit, corners); // if (flag) // { // //hitObj = EntitiesManager.Instance.GetEntityByID(data.gameObjID); // removeNoMainCorners(corners); // StartCoroutine(GoToDestination(data)); // } // } // } //} } //else //{ // Debug.Log("不能移动"); // // ResourceLoadWindow.Instance.LoadTextHintWindow("不能移动", 1f); //} } void removeNoMainCorners(List corners) { for (int i = 0; i < corners.Count - 1; i++) { for (int k = corners.Count - 2; k > i; k--) { float distance = Vector3.Distance(corners[i], corners[k]);//计算两点的距离 if (distance < 5) { for (int j = k; j > i; j--) { corners.RemoveAt(j); } break; } } } } bool setPathCorners(Vector3 sourcePosition, Vector3 targetPosition, List corners) { NavMeshPath NavMeshPath = new NavMeshPath(); NavMesh.CalculatePath(sourcePosition, targetPosition, filter, NavMeshPath); Vector3[] b = NavMeshPath.corners; if (b.Length == 1) { //Debug.Log("断裂"); return false; } if (NavMeshPath.status == NavMeshPathStatus.PathComplete) { //Debug.Log("PathComplete"); foreach (Vector3 corner in b) { if (!corners.Contains(corner)) { corners.Add(corner); } } return true; } else if (NavMeshPath.status == NavMeshPathStatus.PathPartial) { if (Vector3.Distance(b[b.Length - 1], lastPosition) == 0) { //Debug.Log("(" + sourcePosition.x + "," + sourcePosition.y + "," + sourcePosition.z + ")、(" + lastPosition.x + "," + lastPosition.y + "," + lastPosition.z + ")"); //Debug.Log("进入死循环"); return false; } foreach (Vector3 corner in b) { if (!corners.Contains(corner)) { corners.Add(corner); } } lastPosition = sourcePosition; return setPathCorners(b[b.Length - 1], targetPosition, corners); } else if (NavMeshPath.status == NavMeshPathStatus.PathInvalid) { return false; } else { return false; } } IEnumerator GoToDestination(TrappedPathFindingCmdArgs data) { int i = 1; while (i < corners.Count) { NavMeshPath NavMeshPath = new NavMeshPath(); NavMesh.CalculatePath(transform.position, corners[i], filter, NavMeshPath); if(agent.enabled) agent.SetDestination(corners[i]); while (agent.pathPending) yield return null; //wait until we reached this position float remain = Vector3.Distance(transform.position, corners[i]); while (remain == Mathf.Infinity || remain - agent.stoppingDistance > float.Epsilon) { remain = Vector3.Distance(transform.position, corners[i]); yield return null; } var objinfo = GetComponent(); setFloorMessage(); i++; } //NavMeshPath NavMeshPath = new NavMeshPath(); //NavMesh.CalculatePath(transform.position, data.hitPoint, filter, NavMeshPath); //Vector3[] corns = NavMeshPath.corners; //while (i < corns.Length) //{ // agent.isStopped = false; // agent.SetDestination(corns[i]); // //wait until we reached this position // while (agent.pathPending) // yield return null; // while (agent.remainingDistance > agent.stoppingDistance) // { // yield return null; // } // i++; //} } private void setFloorMessage() { //设置寻路对象楼层属性 Vector3 adPos2 = transform.position; Ray ray = new Ray(adPos2, -Vector3.up); RaycastHit hit = new RaycastHit(); if (Physics.Raycast(ray, out hit, 1000, LayerMask.GetMask("SoldierRoad", "CarRoad"))) { if (hit.transform.gameObject.GetComponent()) { CloneGameObjInfo msg = GetComponent(); CloneGameObjInfo hitinfo = hit.transform.gameObject.GetComponent(); msg.buildNum = hitinfo.buildNum; msg.floorNum = hitinfo.floorNum; msg.interlayerNum = hitinfo.interlayerNum; return; } } } public List GetPathCornert(Vector3 endpoint, List corners) { List gocornert = new List(); bool isexit = SetPathCorners(transform.position, endpoint, corners); if (isexit) { gocornert = corners; } return gocornert; } /// /// 设置寻路路径上的拐角点集合,并返回是否有可寻路路径 /// /// 起点位置 /// 终点位置 /// 可寻路路径拐角点集合 /// 返回是否有可寻路路径 private bool SetPathCorners(Vector3 startingPos, Vector3 destinationPos, List corners) { NavMesh.CalculatePath(startingPos, destinationPos, filter, path); Vector3[] tempCorners = new Vector3[path.corners.Length]; tempCorners = path.corners; if (tempCorners.Length < 2) { return false; } if (path.status == NavMeshPathStatus.PathComplete) { foreach (Vector3 corner in tempCorners) { if (!corners.Contains(corner)) { corners.Add(corner); } } return true; } else if (path.status == NavMeshPathStatus.PathPartial) { foreach (Vector3 corner in tempCorners) { if (!corners.Contains(corner)) { corners.Add(corner); } } if (corners.Contains(tempCorners[tempCorners.Length - 1])) {//1. 如果两个独立不连通的寻路区域会出现此种情况,这种情况下表明到达不了,返回false。 //2. 如果两个寻路区域,找不到最短到达路径,但有其他更长的路径可以到达,也可能出现此种情况 return false; } else { return SetPathCorners(tempCorners[tempCorners.Length - 1], destinationPos, corners); } } else if (path.status == NavMeshPathStatus.PathInvalid) { return false; } else { return false; } } public void Stopall() { StopAllCoroutines(); } }