float CaculateNodeCost(PlayerAtt player, PathFindNodeItem a, PathFindNodeItem b) { bool needClimb = false; bool needJump = false; if (b.Height - a.Height > grid.CanPathThrethhold) { needClimb = true; } else if (a.Height - b.Height > grid.CanPathThrethhold) { needJump = true; } float distance = getDistanceNodes(a, b); float cost = distance / player.moveSpeed; if (needClimb) { if (player.climbSpeed > 0.0f) { float climpcost = (b.Height - a.Height) / player.climbSpeed; cost += climpcost; } else { cost = -1.0f; } } if (needJump) { } return(cost); }
// A*寻路 void FindingPath(PlayerAtt player, Vector3 s, Vector3 e) { PathFindNodeItem startNode = grid.getItem(s); PathFindNodeItem endNode = grid.getItem(e); List <PathFindNodeItem> openSet = new List <PathFindNodeItem>(); HashSet <PathFindNodeItem> closeSet = new HashSet <PathFindNodeItem>(); openSet.Add(startNode); while (openSet.Count > 0) { PathFindNodeItem curNode = openSet[0]; for (int i = 0, max = openSet.Count; i < max; i++) { if (openSet[i].fCost <= curNode.fCost) { curNode = openSet[i]; } } openSet.Remove(curNode); closeSet.Add(curNode); // 找到的目标节点 if (curNode == endNode) { Debug.Log("cost is :" + curNode.gCost.ToString()); generatePath(startNode, endNode); return; } // 判断周围节点,选择一个最优的节点 foreach (var item in grid.getNeibourhood(curNode)) { // 如果是墙或者已经在关闭列表中 float neibourCost = CaculateNodeCost(player, curNode, item); if (neibourCost == -1.0f || closeSet.Contains(item)) { continue; } // 计算当前相领节点现开始节点距离 float newCost = curNode.gCost + neibourCost; // 如果距离更小,或者原来不在开始列表中 if (newCost < item.gCost || !openSet.Contains(item)) { // 更新与开始节点的距离 item.gCost = newCost; // 更新与终点的距离 item.hCost = getDistanceNodes(item, endNode) / player.moveSpeed; // 更新父节点为当前选定的节点 item.parent = curNode; // 如果节点是新加入的,将它加入打开列表中 if (!openSet.Contains(item)) { openSet.Add(item); } } } } generatePath(startNode, null); }
// Use this for initialization void Start() { grid = GetComponent <Grid>(); player = GetComponent <PlayerAtt>(); }