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.
348 lines
13 KiB
348 lines
13 KiB
4 years ago
|
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();
|
||
|
}
|
||
|
}
|