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.
347 lines
13 KiB
347 lines
13 KiB
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<Vector3> corners = new List<Vector3>(); |
|
private Vector3 lastPosition; |
|
public bool pathFindEnable; |
|
private NavMeshPath path; |
|
/// <summary> |
|
/// 是否被引导 |
|
/// </summary> |
|
private bool guidance; |
|
private CloneGameObjInfo gameobjinfo; |
|
void Start() |
|
{ |
|
pathFindEnable = true; |
|
NavMeshPath = new NavMeshPath(); |
|
agent = GetComponent<NavMeshAgent>(); |
|
filter = new NavMeshQueryFilter(); |
|
filter.agentTypeID = agent.agentTypeID; |
|
filter.areaMask = agent.areaMask; |
|
path = new NavMeshPath(); |
|
gameobjinfo = GetComponent<CloneGameObjInfo>(); |
|
} |
|
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<TrappedMoveFree>().targetPosition = pointhit; |
|
//long gameID = data.gameObjID; |
|
long selfID = data.gameObjIdSelf; |
|
// List<long> movelist = data.MoveIdlist; |
|
//自由状态 |
|
if (selfID != 0) |
|
{ |
|
if (selfID == GetComponent<BaseGameObjInfo>().gameObjID) |
|
{ |
|
GetComponent<TrappedMoveFree>().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<TrappedMoveFree>().Guidance) |
|
{ |
|
PathFindSyncData pathsync = new PathFindSyncData(); |
|
pathsync.SendUserID = CurrentUserInfo.mySelf.Id; |
|
pathsync.TargetPoint = data.hitPoint; |
|
pathsync.TrappedMeetDangerous = data.MeetDangerous; |
|
pathsync.gameObjID = GetComponent<BaseGameObjInfo>().gameObjID; |
|
pathsync.gameObjType = GetComponent<BaseGameObjInfo>().gameObjType; |
|
pathsync.UserID = GetComponent<BaseGameObjInfo>().UserID; |
|
pathsync.trappedTargetpoint = pointhit; |
|
NetworkManager.Default.SendAsync(/*CurrentUserInfo.mySelf.Id,*/ "PATHFIND_SYNC", pathsync); |
|
} |
|
} |
|
else |
|
{ |
|
if(GetComponent<TrappedMoveFree>().Guidance) |
|
{ |
|
LoadPromptWin.Instance.LoadTextPromptWindow("被困人员无法到达下一个引导点", 1f); |
|
} |
|
} |
|
} |
|
} |
|
////被移动状态 |
|
//else |
|
//{ |
|
// if (movelist.Count > 0 && GetComponent<TrappedMoveFree>().MoveFireman == fireman) |
|
// { |
|
// if (movelist.Contains(GetComponent<BaseGameObjInfo>().gameObjID)) |
|
// { |
|
// GetComponent<TrappedMoveFree>().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<Vector3> 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<Vector3> 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<BaseGameObjInfo>(); |
|
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>()) |
|
{ |
|
CloneGameObjInfo msg = GetComponent<CloneGameObjInfo>(); |
|
CloneGameObjInfo hitinfo = hit.transform.gameObject.GetComponent<CloneGameObjInfo>(); |
|
msg.buildNum = hitinfo.buildNum; |
|
msg.floorNum = hitinfo.floorNum; |
|
msg.interlayerNum = hitinfo.interlayerNum; |
|
return; |
|
} |
|
} |
|
} |
|
public List<Vector3> GetPathCornert(Vector3 endpoint, List<Vector3> corners) |
|
{ |
|
List<Vector3> gocornert = new List<Vector3>(); |
|
bool isexit = SetPathCorners(transform.position, endpoint, corners); |
|
if (isexit) |
|
{ |
|
gocornert = corners; |
|
} |
|
return gocornert; |
|
} |
|
/// <summary> |
|
/// 设置寻路路径上的拐角点集合,并返回是否有可寻路路径 |
|
/// </summary> |
|
/// <param name="startingPos">起点位置</param> |
|
/// <param name="destinationPos">终点位置</param> |
|
/// <param name="corners">可寻路路径拐角点集合</param> |
|
/// <returns>返回是否有可寻路路径</returns> |
|
private bool SetPathCorners(Vector3 startingPos, Vector3 destinationPos, List<Vector3> 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(); |
|
} |
|
}
|
|
|