// ------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------ protected void Update() { if (!player.getManageMode()) { CloseMessagePanel(); CloseMessageDetailedPanel(); } //if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) && GUIUtility.hotControl == 0) if (Input.GetMouseButtonDown(0)) { // check if clicked on a tile and make it selected Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { // should be a tile since I have nothing else in scene that has a collider // I remove the "Tile " bit from name to get the tile number (node index) GameObject go = hit.collider.gameObject; string tileIndexName = go.name.Replace("Tile ", ""); int idx = -1; if (int.TryParse(tileIndexName, out idx)) { { //if (false == invalidNodes.Contains(grid[idx])) { /* if (Input.GetMouseButtonDown(1)) // clic droit * { * if (grid[idx] != selectedNode) * { * altSelectedNode = grid[idx]; * } * } * else // clic gauche*/ { if (grid[idx] != altSelectedNode) { selectedNode = grid[idx]; if (hit.transform != null) { Debug.Log("Click gauche sur la map"); Vector3 position = hit.transform.position; if (!isNodeAlreadyOccuped()) { addBuildingToScene(position); alreadyOccupedCells.Add(selectedNode); } else { Debug.Log("Cell occuped"); } } } } } } } } } }
// ------------------------------------------------------------------------------------------------------------ protected void Update() { if ((Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1)) && GUIUtility.hotControl == 0) { // check if clicked on a tile and make it selected Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { // should be a tile since I have nothing else in scene that has a collider // I remove the "Tile " bit from name to get the tile number (node index) GameObject go = hit.collider.gameObject; string tileIndexName = go.name.Replace("Tile ", ""); int idx = -1; if (int.TryParse(tileIndexName, out idx)) { ClearMarkedNodes(); if (SampleGUI.Instance.markInvalids) { if (invalidNodes.Contains(grid[idx])) { invalidNodes.Remove(grid[idx]); go.GetComponent <Renderer>().material.color = Color.white; } else { invalidNodes.Add(grid[idx]); go.GetComponent <Renderer>().material.color = Color.black; } } else { if (false == invalidNodes.Contains(grid[idx])) { if (Input.GetMouseButtonDown(1)) { if (grid[idx] != selectedNode) { altSelectedNode = grid[idx]; } } else { if (grid[idx] != altSelectedNode) { selectedNode = grid[idx]; } } } } UpdateMarked(); GeneratePath(); } } } }
// this is called when the object is clicked on protected void OnMouseUpAsButton() { gameObject.SetActive(false); // find the two nodes MapNavNode n1 = map.NodeAt <MapNavNode>((int)node1.x, (int)node1.y); MapNavNode n2 = map.NodeAt <MapNavNode>((int)node2.x, (int)node2.y); // tell the node to set link data with node 2 to zero(0) n1.UpdateOrCreateLinkData(n2.idx, 0, map); }
private void FocusCamera() { Vector3 p = Vector3.zero; int x = (int)(mapHorizontalSize / 2); int y = (int)(mapVerticalSize / 2); MapNavNode n = NodeAt <MapNavNode>(x, y); if (n != null) { p = n.position; } Camera.main.GetComponent <CameraController>().Refocus(p); }
// ------------------------------------------------------------------------------------------------------------ #region callbacks /// <summary> /// This will be called by map.NodesAround to find out if the target node is valid /// and how much it will cost to move to that node. In my case I do not have extra /// cost to move from tile to tile, so I will simply return 1. The only condition /// is that units may not move to tile that are too high/ low; in that case I /// need to return 0. /// </summary> protected virtual float OnNodeCostCallback(MapNavNode fromNode, MapNavNode toNode) { if ((toNode as NavalTile).unit != null) { return(0f); // there is a unit on target node } int heightDiff = Mathf.Abs(fromNode.h - toNode.h); if (heightDiff >= 2) { return(0f); // too height } return(1f); }
// ------------------------------------------------------------------------------------------------------------ protected void LateUpdate() { // Update the map markers by checking where the mouse is over the // map and calculating which hexa node is around that position RaycastHit hit; Ray r = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(r, out hit)) { MapNavNode n = NodeAtWorldPosition <MapNavNode>(hit.point); ShowMarkersAround(n); } }
// ------------------------------------------------------------------------------------------------------------ #region system protected void Start() { // create the unit GameObject go = Instantiate(unitFab); unitTr = go.transform; // position the unit at the middle tile int x = map.mapHorizontalSize / 2; int y = map.mapVerticalSize / 2; node = map.NodeAt <MapNavNode>(x, y); unitTr.position = node.position; }
private void ShowMarkersAround(MapNavNode n) { HideAllMarkers(); if (n == null) { return; } List <MapNavNode> nodes = NodesAround <MapNavNode>(n, false, true, null); for (int i = 0; i < nodes.Count; i++) { markers[i].SetActive(true); markers[i].transform.position = nodes[i].position + new Vector3(0f, 20f, 0f); } }
private bool CheckIfValidNode(MapNavNode toNode) { Sample4Tile n = toNode as Sample4Tile; // this will help prevent a border being drawn around the active unit's tile // also see the IF(neighbours[j] != activeUnit.tile ...) that must be used above if (n == activeUnit.tile) { return(true); } // can't move to a tile that has a unit on it if (n.unit != null) { return(false); } // finally, return tile's default state return(toNode.isValid); }
/// <summary> /// I've kept most of what Sample4Controller.OnNodeCostCallback did (see its comments) /// The big difference is that the Node Link Data is looked at to determine if there /// is a wall in the way. Basically any link data that exist and is not set to 0 /// will be considered a wall. I've also added a door which when click, will /// set its associated node data to 0. See Sample6Door.cs /// </summary> protected override float OnNodeCostCallback(MapNavNode fromNode, MapNavNode toNode) { // get the link data between fromNode and toNode MapNavNodeLink ld = fromNode.GetLinkData(toNode.idx); // if "ld" is null then there is no link data for them if (ld != null) { // if the data is not 0 then there is a wall or door in way // you can decide what the data (numbers) means in your own game // but in this simple example any non-zero value blocks movement if (ld.data != 0) { return(0f); // return 0, meaning that target node is invalid } } // the rest is same as Sample 4 return(base.OnNodeCostCallback(fromNode, toNode)); }
private void MoveUnit(int dir) { // get the node that is in the specified direction // null is returned then there is no valid node there // and the unit should not move there // the direction to find the node in is from current // node + the value provided by the Neighbours4 MapNavNode n = map.NodeAt <MapNavNode>(node.q + Neighbours4[dir, 0], node.r + Neighbours4[dir, 1]); if (n != null) { // keep track of the node the unit is on node = n; // you could of course use some tweening to smoothly move the // unit to the target position but ill just set it directly unitTr.position = node.position; } }
// this is called by the Path function to find out what the cost is to move from one // node to the neighbouring node, or if the move is even allowed private float OnNodeCostCallback(MapNavNode fromNode, MapNavNode toNode) { return(invalidNodes.Contains(toNode) ? 0f : 1f); }
/// <summary> /// I override this callback so that I can respond on the grid being /// changed and place/ update the actual tile objects /// </summary> public override void OnGridChanged(bool created) { // The parent object that will hold all the instantiated tile objects Transform parent = gameObject.transform; // Remove existing tiles and place new ones if map was (re)created // since the number of tiles might be different now if (created) { selectedNode = null; altSelectedNode = null; invalidNodes.Clear(); ClearMarkedNodes(); GeneratePath(); for (int i = parent.childCount - 1; i >= 0; i--) { if (Application.isPlaying) { // was called at runtime Object.Destroy(parent.GetChild(i).gameObject); } else { // was called from editor Object.DestroyImmediate(parent.GetChild(i).gameObject); } } // Place tiles according to the generated grid for (int idx = 0; idx < grid.Length; idx++) { // make sure it is a valid node before placing tile here if (false == grid[idx].isValid) { continue; } // create a new tile GameObject go = (GameObject)Instantiate(gridOrientation == GridOrientation.FlatTop ? tileFlatFab : tilePointyFab); go.name = "Tile " + idx.ToString(); go.transform.position = grid[idx].position; go.transform.parent = parent; } } // else, simply update the position of existing tiles else { for (int idx = 0; idx < grid.Length; idx++) { // make sure it is a valid node before processing it if (false == grid[idx].isValid) { continue; } // Since I gave the tiles proper names I can easily find them by name GameObject go = parent.Find("Tile " + idx.ToString()).gameObject; go.transform.position = grid[idx].position; } } // focus the camera on the center tile if (Application.isPlaying) { FocusCamera(); } }
// this is called by NodesAround when wanting to know if the specified tile is valid // in the example the user can mark certain nodes "invalid" so I will use that here // in a game this could represent a node that is occupied by a unit when you want // to find out which nodes a selected unit may move to private bool OnValidateNode(MapNavNode node) { return(false == invalidNodes.Contains(node)); }
// this is called by the Path function to find out what the cost is to move from one // node to the neighbouring node, or if the move is even allowed private float OnNodeCostCallback(MapNavNode fromNode, MapNavNode toNode) { return(1f); }
// this is called by NodesAround when wanting to know if the specified tile is valid // in the example the user can mark certain nodes "invalid" so I will use that here // in a game this could represent a node that is occupied by a unit when you want // to find out which nodes a selected unit may move to private bool OnValidateNode(MapNavNode node) { return(true); }