/// <summary> /// 所有共用vertex的三角形 /// </summary> private static void GetAllNodesByVert(ref List <CheckNodeInfo> nodeInfos, NavMeshNode startNode, Int3 vertex) { if (nodeInfos == null) { nodeInfos = new List <CheckNodeInfo>(); } for (int i = 0; i < nodeInfos.Count; i++) { CheckNodeInfo info2 = nodeInfos[i]; if (info2.node == startNode) { return; } } int num2 = -1; if (startNode.v0 == vertex) { num2 = 0; } else if (startNode.v1 == vertex) { num2 = 1; } else if (startNode.v2 == vertex) { num2 = 2; } else { return; } CheckNodeInfo item = new CheckNodeInfo(); item.vi = num2; item.node = startNode; item.v0 = startNode.GetVertex(num2 % 3); item.v1 = startNode.GetVertex((num2 + 1) % 3); item.v2 = startNode.GetVertex((num2 + 2) % 3); nodeInfos.Add(item); if (startNode.connections != null) { for (int j = 0; j < startNode.connections.Length; j++) { NavMeshNode node = startNode.graph.GetNode(startNode.connections[j]) as NavMeshNode; if (node != null) { GetAllNodesByVert(ref nodeInfos, node, vertex); } } } }
/// <summary> /// /// </summary> /// <param name="node"></param> /// <param name="startEdge"></param> /// <param name="srcLoc"></param> /// <param name="destLoc"></param> /// <param name="state"></param> /// <param name="result">实际可移动到的点</param> private static void MoveFromNode(NavMeshNode node, int startEdge, Int3 srcLoc, Int3 destLoc, out Int3 result) { result = srcLoc; while (node != null) { int num; int num10; int count = 2; // 当前在顶点上 if (node.IsVertex(srcLoc, out num)) { // 找到所有包含srcLoc这顶点的三角形 Int3 vertex = node.GetVertex(num); List <CheckNodeInfo> nodeInfos = null; GetAllNodesByVert(ref nodeInfos, node, vertex); // 找到其中将要穿过的三角形 NavMeshNode node2 = null; int vi = -1; for (int i = 0; i < nodeInfos.Count; i++) { CheckNodeInfo info = nodeInfos[i]; if ((!checkedNodes.Contains(info.node) && !VectorMath.RightXZ(info.v0, info.v2, destLoc)) && VectorMath.RightOrColinearXZ(info.v0, info.v1, destLoc)) { node2 = info.node; vi = info.vi; break; } } if (node2 != null) { node = node2; // 将要穿过的边 startEdge = (vi + 1) % 3; count = 1; } else { int num6 = -1; VFactor factor3 = new VFactor(); factor3.nom = -2L; factor3.den = 1L; VFactor factor = factor3; for (int j = 0; j < nodeInfos.Count; j++) { CheckNodeInfo info2 = nodeInfos[j]; if (!checkedNodes.Contains(info2.node)) { int num8; VFactor factor2 = info2.GetCosineAngle(destLoc, out num8); if (factor2 > factor) { factor = factor2; num6 = num8; node2 = info2.node; } } } if (node2 != null) { MoveAlongEdge(node2, num6, srcLoc, destLoc, out result, true); break; } } } // 将要穿过的边 int edge = -1; if (startEdge == -1) { edge = node.EdgeIntersect(srcLoc, destLoc); } else { edge = node.EdgeIntersect(srcLoc, destLoc, startEdge, count); } // 不会穿越边 if (edge == -1) { if (node.ContainsPoint(destLoc)) { // 三角形内移动 result = destLoc; if (MoveAxisY) { CalculateY(ref result, node); } } else { // 沿边所在直线移动 edge = node.GetColinearEdge(srcLoc, destLoc); if (edge != -1) { MoveAlongEdge(node, edge, srcLoc, destLoc, out result, true); } } break; } // 会穿过边,则看相邻三角形 NavMeshNode neighborByEdge = node.GetNeighborByEdge(edge, out num10); if (neighborByEdge != null) { node = neighborByEdge; startEdge = num10 + 1; count = 2; } else { MoveAlongEdge(node, edge, srcLoc, destLoc, out result, true); break; } } }