网上演练贵港万达广场(人员密集)
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

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();
}
}