/// <summary> /// Counts the distance from this node to the target node, using the layout linking as guideline on how to count. /// Similar to calculating the path to the target, ignoring obstacles, and taking that distance. Returns 0 on error. /// </summary> public int TileCountTo(TileNode targetNode) { TileNode[] path = mapnav.GetPath(this, targetNode); if (path == null) { return(0); } return(path.Length); }
public void OnSceneGUI() { MapNav mapNav = Target; float y = 0.1f; if (curProcessType == ProcessType.None) { return; } if (curProcessType == ProcessType.Set || curProcessType == ProcessType.Clear) { Plane groundPlane = new Plane(Vector3.up, Vector3.zero); float rayDistance; Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); if (groundPlane.Raycast(ray, out rayDistance)) { Vector3 hitPoint = ray.GetPoint(rayDistance); if (hitPoint.x >= 0.0f && hitPoint.x <= mapNav.gridXNum * MapGrid.Width && hitPoint.z >= 0.0f && hitPoint.z <= mapNav.gridZNum * MapGrid.Height) { Handles.color = Color.black; float _radius = radius * 0.5f; Handles.DrawPolyLine(new Vector3[] { new Vector3(hitPoint.x - _radius * MapGrid.Width, y, hitPoint.z - _radius * MapGrid.Height), new Vector3(hitPoint.x - _radius * MapGrid.Width, y, hitPoint.z + _radius * MapGrid.Height), new Vector3(hitPoint.x + _radius * MapGrid.Width, y, hitPoint.z + _radius * MapGrid.Height), new Vector3(hitPoint.x + _radius * MapGrid.Width, y, hitPoint.z - _radius * MapGrid.Height), new Vector3(hitPoint.x - _radius * MapGrid.Width, y, hitPoint.z - _radius * MapGrid.Height) }); if (Event.current.type == EventType.MouseDown || Event.current.type == EventType.MouseDrag) { var grid = new MapGrid(hitPoint); for (int _z = grid.z - Mathf.RoundToInt(_radius); _z <= grid.z + Mathf.RoundToInt(_radius); ++_z) { if (_z < 0) { continue; } if (_z > mapNav.gridZNum - 1) { continue; } for (int _x = grid.x - Mathf.RoundToInt(_radius); _x <= grid.x + Mathf.RoundToInt(_radius); ++_x) { if (_x < 0) { continue; } if (_x > mapNav.gridXNum - 1) { continue; } Vector3 position = mapNav.GetWorldPosition(new MapGrid() { x = _x, z = _z }); if (Mathf.Abs(position.x - hitPoint.x) <= _radius * MapGrid.Width && Mathf.Abs(position.z - hitPoint.z) <= _radius * MapGrid.Height) { switch (curProcessType) { case ProcessType.Set: mapNav[_x, _z] |= curTileType; break; case ProcessType.Clear: mapNav[_x, _z] &= ~curTileType; break; default: throw new System.NotImplementedException(); } } } } } } } } else if (curProcessType == ProcessType.FindPath) { if (Event.current.type == EventType.MouseDown) { Plane groundPlane = new Plane(Vector3.up, Vector3.zero); float rayDistance; Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); if (groundPlane.Raycast(ray, out rayDistance)) { Vector3 hitPoint = ray.GetPoint(rayDistance); if (hitPoint.x >= 0.0f && hitPoint.x <= mapNav.gridXNum * MapGrid.Width && hitPoint.z >= 0.0f && hitPoint.z <= mapNav.gridZNum * MapGrid.Height) { if (bSampleStart) { vecStart = hitPoint; } else { vecEnd = hitPoint; } bSampleStart = !bSampleStart; MapGrid gridEnd; if (mapNav.GetNearestValidGrid(new MapGrid(vecStart), new MapGrid(vecEnd), out gridEnd, TileType.TileType_Walk)) { path = mapNav.GetPath(new MapGrid(vecStart), gridEnd, TileType.TileType_Walk); } else { path.Clear(); } } } } Handles.color = Color.red; Handles.CubeCap(0, vecStart, new Quaternion(0, 0, 0, 1), 0.1f); Handles.color = Color.blue; Handles.CubeCap(0, vecEnd, new Quaternion(0, 0, 0, 1), 0.1f); if (path.Count > 0) { Handles.color = Color.black; Vector3 lastPoint = vecStart; lastPoint.y = y; foreach (MapGrid grid in path) { Vector3 curPoint = mapNav.GetWorldPosition(grid); curPoint.y = y; Handles.color = Color.black; Handles.DrawLine(lastPoint, curPoint); lastPoint = curPoint; Handles.color = Color.cyan; Handles.CubeCap(0, curPoint, new Quaternion(0, 0, 0, 1), 0.1f); } } } HandleUtility.Repaint(); switch (Event.current.type) { case EventType.MouseUp: case EventType.MouseDown: case EventType.MouseDrag: case EventType.MouseMove: Event.current.Use(); break; } }
public TileNode[] GetPathTo(MapNav map, TileNode targetNode) { return(map.GetPath(node, targetNode, tileLevel)); }
// 移动 断开和当前节点链接->移动->链接至目标节点 public bool MoveTo(MapNav map, TileNode targetNode, ref int moves) { if (moves == 0) { return(false); } TileNode[] path = map.GetPath(node, targetNode, tileLevel); if (path == null) { return(false); } if (path.Length == 0) { return(false); } int useMoves = path.Length; if (moves >= 0) { if (moves <= useMoves) { useMoves = moves; moves = 0; } else { moves -= useMoves; } } else { moves = path.Length; } node.units.Remove(this); node = path[useMoves - 1]; node.units.Add(this); isMoving = true; System.Collections.Hashtable opt = iTween.Hash( "orienttopath", true, "easetype", "linear", "oncomplete", "_OnCompleteMoveTo", "oncompletetarget", gameObject); if (!tiltToPath) { opt.Add("axis", "y"); } if ((adjustNormals || adjustToCollider) && adjustmentLayerMask != 0) { opt.Add("onupdate", "_OnMoveToUpdate"); opt.Add("onupdatetarget", gameObject); } if (path.Length > 1) { Vector3[] points = new Vector3[useMoves]; for (int i = 0; i < useMoves; i++) { points[i] = path[i].transform.position; } endPointToReach = points[points.Length - 1]; opt.Add("path", points); opt.Add("speed", ((move_speedMulti * useMoves) + 1f) * move_speed); iTween.MoveTo(gameObject, opt); } else { endPointToReach = path[0].transform.position; opt.Add("position", endPointToReach); opt.Add("speed", move_speed); iTween.MoveTo(gameObject, opt); } return(true); }
/// <summary> /// Move the unit to the specified target node. Will make a callback with /// eventCode=1 when done moving if a callback was set in Init() /// iTween (free on Unity Asset Store) is used to move the Unit /// </summary> /// <param name="map">NavMap to use</param> /// <param name="targetNode">Node to reach</param> /// <param name="moves"> /// Number of moves that can be use to reach target. Pass (-1) to ignore this. /// The unit will move as close as possible if not enough moves given. /// Moves will be set to moves - actual_moves_use; or if -1 passed, it will be set to number of moves that was taken. /// </param> /// <returns>True is the unit started moving towards the target</returns> public bool MoveTo(MapNav map, TileNode targetNode, ref int moves) { if (moves == 0) { return(false); } TileNode[] path = map.GetPath(this.node, targetNode, this.tileLevel); if (path == null) { return(false); } if (path.Length == 0) { return(false); } // check if enough moves to reach destination int useMoves = path.Length; if (moves >= 0) { if (moves <= useMoves) { useMoves = moves; moves = 0; } else { moves -= useMoves; } } else { moves = path.Length; } // unlink with current node and link with destination node this.node.units.Remove(this); this.node = path[useMoves - 1]; this.node.units.Add(this); isMoving = true; // *** start jumping from tile to tile if (jumpMovement) { _jump_points = new Vector3[useMoves]; _jump_pointIdx = 0; for (int i = 0; i < useMoves; i++) { _jump_points[i] = path[i].transform.position; } _JumpToNextPoint(); } // *** start normal movement from tile to tile else { System.Collections.Hashtable opt = iTween.Hash( "orienttopath", true, "easetype", "linear", "oncomplete", "_OnCompleteMoveTo", "oncompletetarget", gameObject); if (!tiltToPath) { opt.Add("axis", "y"); } if ((adjustNormals || adjustToCollider) && adjustmentLayerMask != 0) { opt.Add("onupdate", "_OnMoveToUpdate"); opt.Add("onupdatetarget", gameObject); } if (path.Length > 1) { Vector3[] points = new Vector3[useMoves]; for (int i = 0; i < useMoves; i++) { points[i] = path[i].transform.position; } endPointToReach = points[points.Length - 1]; opt.Add("path", points); opt.Add("speed", ((moveSpeedMulti * useMoves) + 1f) * moveSpeed); iTween.MoveTo(this.gameObject, opt); } else { endPointToReach = path[0].transform.position; opt.Add("position", endPointToReach); opt.Add("speed", moveSpeed); iTween.MoveTo(this.gameObject, opt); } } return(true); }