Search Unity

  1. Unity 2019.4 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  3. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Tile Based Map Nav

Discussion in 'Assets and Asset Store' started by Leslie-Young, Jun 2, 2012.

  1. Anymeese

    Anymeese

    Joined:
    May 27, 2013
    Posts:
    18
    Hey Leslie, I have a couple questions for you:

    I purchased the older Map Nav (Version 1 I guess) this past summer and it's been fantastic! But now suddenly, nodeLinks is consistently returning null on a node that very clearly has 4 connected nodes. Have you run into or heard or anything like this? Any idea what causes it or how to fix it?

    And does version 2 have a Line of Sight system (where units' vision is blocked by walls, higher elevation nodes, etc)?
     
  2. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    There is no line of sight function in #2 but I'll make a note to look into this cause I should probably add a "get straight line" function. In Battlemass 1 I used a simple raycast to check if there was a wall (they had coliders). IN BM2 the ranged units shoot up (and over) so that "walls" was not a problem.

    I'll need to see how you use v1 to find out what could be causing a null in the nodeLinks. They are set up during Awake() of the mapnav so do not try access them then.
     
  3. Anymeese

    Anymeese

    Joined:
    May 27, 2013
    Posts:
    18
    Thanks for the super quick reply! That might actually be causing the issue, but is there a way to make the Start() or Awake() of my other scripts wait until Awake() of MapNav is finished (or equivalently, make MapNav's Awake() run before any other scripts)?
     
  4. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    I checked the code again and it is done in Start(); so you can't use Awake or Start.
    If you want to try, open MapNav.cs and move the code in LinkNodes() call in Start to Awake in that script. Moving ShowAllTileNodes(false); might be save too. Try this and see if it works. Can't remember why I placed them in Start rather than Awake (it has been year+ since I worked with that code).

    If it does not work then there is an option to set script execution order but I would rather just change the script that needs to access the mapnav than messing with the order thing. For example, you could try ..

    Code (CSharp):
    1. IEnumerator Start()
    2. {
    3.     // wait a frame
    4.     yield return null;
    5.  
    6.     // now access mapnav
    7. }
    but if rest of your code in update depends on something you init in Start then you might be better off initing in your Update so that the data is ready before the rest of your code wants to access it. Add a bool flag that you check in the update before going on

    Code (CSharp):
    1. void Update()
    2. {
    3.     if (needInit)
    4.     {
    5.         needInit = false;
    6.         // access mapnav
    7.         // ...
    8.     }
    9. }
     
  5. Anymeese

    Anymeese

    Joined:
    May 27, 2013
    Posts:
    18
    Using IEnumerator Start() instead of void worked perfectly :) Thank you very much for the help!
     
  6. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,545
  7. Anymeese

    Anymeese

    Joined:
    May 27, 2013
    Posts:
    18
    Hi Leslie, I have one more question for you!

    Here is a sceenshot of my game atm:


    I want a List<TileNode> of all nodes in the red and blue areas -- the outer-most ring of vision. It's easy when in the center of the map, but when near the edge like this, how could I go about getting the nodes highlighted in blue?
     
  8. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    One thing I can think of...

    Try a combination of the NodesRing() (list1) to get the initial ring (red) and NodesAround(with_range) (list2) to get everything in range. Now run through list 2 and check which nodes are not yet in list 1 and has invalid neighbour nodes. The one with invalid neighbours are most like on edge. You can get the complete list of neighbours (incl markers for invalid ones) via the includeInvalid option in NodesAround().

    Of course you do not wat to do this per frame, so cache that list.
     
  9. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Hi Leslie,

    Not sure if you or someone already notice that but in Unity 5 (MapNav1) when the MapNav gameobject is unselected in the scene hierarchy,Gizmos are still visible/shown even if all MapNav Gizmos Properties are set to false (gizmoDrawNodes, gizmoDrawLinks, gizmoColorCoding).
    I´m not that familiar with Gizmo or Editor scripting in Unity but I believe some lines of codes in TileNode.cs gizmo #region should be tweaked/edited to solve this problem.

    Thanks.

    Edit :
    For anyone running into the same problem here is an answer from Leslie Young :

    Open TileNode.cs and change all occurrences of GizmoType.Selected to GizmoType.SelectedOrChild.
     
    Last edited: Mar 6, 2015
  10. danish115

    danish115

    Joined:
    Aug 28, 2014
    Posts:
    46
    Can anybody tell me how can i fill my scene from square nodes ?? i have a problem when i create MapNav from the editor it contains only one node. how can i make other nodes.
     
    Last edited: Apr 8, 2015
  11. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    You need to enter a size for the map in the window that came up.
     
  12. danish115

    danish115

    Joined:
    Aug 28, 2014
    Posts:
    46
    "Leslie Young" will you show me the screen shot or refer me any video tutorial, from where the number of nodes may increase.
     
  13. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    > will you show me the screen shot
    Documentation is included in `\Assets\Tile Based Map and Nav\Documentation\doc.pdf` and explains everything.

    04.jpg

    > any unit can not be taget by cam pivot and markers are not shown

    Please rephrase. I do not understand this sentence. As for markers not showing up; make sure you are using a valid Node prefab. The package include some sample prefabs in `\Assets\Tile Based Map and Nav\Prefabs\tile_nodes\`

    > anybody there
    I'm not on this forum 24/7
     
  14. danish115

    danish115

    Joined:
    Aug 28, 2014
    Posts:
    46
    you are awesome man Leslie Young
     
  15. danish115

    danish115

    Joined:
    Aug 28, 2014
    Posts:
    46
    thanks Leslie Young for a great asset. i just want to know one more question.
    i have increased maxMoves which may increase the radius movement of player. when maxMoves = 7 there will be a great lack after reaching the assigned position.
    i also want to know that how can i replace my character from unit and do animation as well.
    it will be highly appreciated and thanks in advance.
     
  16. danish115

    danish115

    Joined:
    Aug 28, 2014
    Posts:
    46
    anxiously waiting for your response.
     
  17. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    > when maxMoves = 7 there will be a great lack after reaching the assigned position

    I do not quite understand what you are asking. What does "great lack" mean?
     
  18. danish115

    danish115

    Joined:
    Aug 28, 2014
    Posts:
    46
    i mean area of the blocks
     
  19. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
  20. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Hi Leslie,

    as intended, using the (oneUnitExceptionAllowMoveOver = true) property allows units to fly and move over others. Everything seems to work fine, but when it comes to the IA logic Im having some issues with this feature. When the IA choses a random TileNode in the range of another one (radius 1) so it can move near to it using MoveTo() (kind of Supportive pattern), sometimes the flying unit stopps at the same TileNode as the target. Simply because the distance to the choosen TileNode is greater than the unit`s current movement points which lead to this situation.
    So how can I prevent the IA from doing this? Maybe changing something on NaviUnit._StartMoving() or .MoveTo()??
     
  21. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Check the TileNode.units property to see if the target is on it before choosing it as a valid node to move to.
     
  22. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    I think you misunderstand me. On a random node from a range of 1 (TargetUnit.GetAllInRange(1)) the AI unit can stand on the choosen node. But it will run out of movement points (CurrentMovementPoints) while moving to the destination and end up on the top of the targted unit (both units in the same node). Anyway the solution is to write a custom method for AI to move and reduce the current movement points when the followedPath last node does contain a unit.
    As always thank you for all time and effort you put into helping us.
     
  23. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Hi again,
    I´ve noticed something weird about TileNode.GetAllInRange() but I´m not sure if it´s should be like it is or simply a bug!!

    AI_Nodes.jpg

    As you can see in the picture : the Target (Air unit : can move on land and water) is standing in a water plan which contains nodes of type "Water" (dark blue nodes). The AI Unit (land unit) will choose a random node in a range of 2 relative to the Target.
    Using Target.GetAllInRange(2,TileType.Land) to choose a valide node for the AI Unit will return 0 nodes which should actually be 5 (see the green nodes on the picture).
    It seems that the validNodesLayer check inside GetAllInRange(2,TileType.Land) is done only for the first range (see the red range) and if none of the 6 nodes meet´s the condition ((node.tileTypeMask & validNodesLayer) == validNodesLayer) the function doesn´t do the check for the rest (see the second orange range). Notice that if only 1 node from the red range is of type land the function will work as intended.
    What I´m missing here o_O ?? this is really driving me insane.

    Thanks.
     
  24. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Is the 1/2 land 1/2 water tiles (in your screenshot) marked as being in the Land node-layer? What are the values of the rest of the parameters send to the function (GetAllInRange)? It takes 5 parameters, not 2.

    Anyway, that function works with what the Unit can move to in range. That is why it will fall out of a node if that node is invalid and not consider its linked nodes.

    I'll PM you with a variation on that function that might work for your needs. MapNav 1 is not longer available on the Asset Store (replaced by MapNav 2) so I can't do an update for it.
     
    Last edited: Jun 29, 2015
  25. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Oh sorry I forgot to mention that. I´m passing true for checkIfUnitInWay ,false for inclMoveMod and incLinkCheck because I dont need those checks for now ==> Target.GetAllInRange(2,TileType.Land,true,false,false).
    And for the nodes : the dark blue ones are marked Water,Air and the rest light blue ones (everything on the green field including the 5 green nodes that I marked) are Land,Air.
     
  26. Deleted User

    Deleted User

    Guest

    Hi,

    I recently purchased this asset and it's been great. There is an error that keeps popping up, and I'm not sure what the issue is (attached as screenshot). Nothing seems to be wrong or not working, but it shows up dozens of times each game.

    Thanks!
     

    Attached Files:

  27. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    As the error indicates. Something was not set. Most likely, the first parameter "node" is null when you called MapNavBase.NodesAround<T>(MapNavNode node, int radius, NodeCostCallback callback);

    I assume you mede changes to sample4controller cause your error indicates errors on lines that does not exist in the original script.
     
  28. Deleted User

    Deleted User

    Guest

    Yeah you were correct. added a if (node != null) that cleared it up. Thanks. The changes I made in the controller allow more than 1 unit to walk at the same time.
     
  29. Deleted User

    Deleted User

    Guest

    I have another question if you don't mind. Trying to get an ai to move to a random tile within a range, and haven't found the right way to put it in the code:

    public void ai_move(GameObject ai_char)
    {
    //AI Move//
    var tmp_unit = ai_char.GetComponent<Sample4Unit>();
    Sample4Tile tmp_node_start = map.NodeAtWorldPosition<Sample4Tile>(ai_char.transform.position); //(hit.point);
    List<int> tmp_nodes = map.NodeIndicesRing(tmp_node_start.idx, 10, 10, null);

    var rand_num = Random.Range(0, tmp_nodes.Count);
    Sample4Tile chosen_node = nodessss[rand_num]; //<<<<This is where I've been stuck.

    if (chosen_node != null && validMoveNodes.Contains(chosen_node)) //&& activeUnit != null
    {
    List<MapNavNode> path = map.Path<MapNavNode>(tmp_unit.tile, chosen_node, OnNodeCostCallback);
    if (path != null)
    {
    unitMoving = true;
    //ClearMoveMarkers();
    tmp_unit.Move(path, OnUnitMoveComplete);
    }
    }
    }

    Basically there is a list of ints in tmp_nodes which I think are node idx's? How do I get an actual Sample4Tile out of those? There doesn't seem to be a function for that in map.

    So any help would be great!

    Thanks.
     
  30. Deleted User

    Deleted User

    Guest

    I figured it out. Here is the solution the line of code I was having trouble with:

    chosen_node = map.grid[rand_num] as Sample4Tile;
     
  31. Xialya

    Xialya

    Joined:
    Oct 4, 2015
    Posts:
    51
    I've got two nodes separated by a low wall which units can cross for 2 move points instead of 1.
    I use node datalinks to calculate the cost while updating the move markers. It works that far.
    However, when moving, it only subtracts 1 to the move points.

    Where should I look to change the cost of moving and adding animations based on datalink?
    How can I actually find which tile the unit is currently crossing and the datalink between this one and the next on path?
     
  32. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Since you are in control of the unit following the path (returned by MapNav) you should know which node the Unit is current on (or moving towards). Do not blindly use the samples and the classes defined for units in the samples. Those scripts are there to learn from and not part of the core system.

    In the Sample4Unit.cs script you will note the Unity does its moving in Update(). There you can see how it uses "path[]: which is an array of nodes. So from this you can already figure out the next node. Simply keep track of the node it was coming from too and take it from there.

    The movement of the Unity can be done in many different ways an you really should create something that works for your game and not base anything off of one of the sample scripts. The other problem with using any sample script is that they were created with the sample's logical needs in mind (or even to be shared among sample scenes) so there will be techniques and code in there that might come in the way of your game or even cause bugs.

    Learn from them, do not use them directly of even as base classes.
     
  33. Xialya

    Xialya

    Joined:
    Oct 4, 2015
    Posts:
    51
    Hello,

    I am trying to figure out how bigger units may occupy 6 or 9 tiles instead of one for smaller units.

    Has someone managed to do it?
    Could you please point me into the right direction? :)
     
  34. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Assuming you are working off the ideas presented by the examples ...

    Each Unit could keep a list of nodes, rather than one. When it binds with a node it will also bind with whatever additional nodes (so for example all neighbours of the main node) so that they seem to be occupied, and of course fill its own list so it knows which nodes to clear/unbind from when it moves off these nodes.

    The path finder callback could then see these nodes as occupied. It will still be tricky to figure out if there is space for a big Unit to fit through. I am thinking one idea could be to also get the neighbour nodes of each node the path might follow (if the Unit is 2 tile radius for example) and include that in decision of he path callback. It will make this path finding slower though.

    Check some of the previous posts. I think there was discussion about wide units before. It might only apply to MapNav 1 though.
     
unityunity