Search Unity

  1. 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

Tile Based Map Nav

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

  1. Raspilicious

    Raspilicious

    Joined:
    Jun 21, 2012
    Posts:
    24
    It has a certain functionality of 'random movement' that lets multiple units move simultaneously, and when their paths collide one of them waits for the other to pass before entering the tile. I haven't played around with this much but that could be what you are looking for.

    I also have a question for users of the package:

    Is there a way to search for the closest node to a particular game object, when that game object is NOT linked to any node?

    For my project I have various buildings which take up multiple tiles, all shaped to fit nicely in the hexagons, and I have most of the functionality working except for linking them with nodes. The way I have programmed it so far is that you drag around a silhouette, which locks to the closest hex, then pressing 'build' creates the building on that spot. The building ends up in the same position of the node (actually multiple nodes, as it covers a few), but the building is not linked to any node and the unit levels aren't changed, so when units pathfind they ignore the building. So is there a way for me to get this to work? Or will I have to redo my building construction and use tile-linked instantiation?
     
  2. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    If you give your nodes colliders then you could use this with raycasts to find out which node(s) the building is over. If you look at my samples you will see the sample square and hex nodes have colliders which allows for mouse clicks on them to be detected. They are turned off by default cause I only turn on the ones I want the player to be able to select, like when he needs to move a unit, so you would have to turn all colliders on before doing the raycast test(s). After the doing the raycasts it will be a simple matter of finding the TileNode component of the object and linking with the node(s).

    You can tell each of the nodes (if more than one) that the unit on it is the building. In the building's class I would keep a list of all the nodes it is over in case I later need to unbind.
     
  3. dbryson

    dbryson

    Joined:
    Nov 9, 2009
    Posts:
    269
    I love this package.

    I have a couple issues:

    1) I notice that the links display between nodes in the Unity editor disappears all the time. Not sure why. The only solution I have found is to disable and then enable the MapNav.

    2) Alignment of the units with terrain/normals of the terrain when moving when the terrain is lightmapped. I think this might be related to fact that Unity doesn't calculate normals for lightmapped terrain. So maybe the normal is not available from the terrain? Whatever, the units don't align with the terrain.
     
  4. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    1) You control the visiblity of node and connection gizmos by the the checkboxes in the mapnav object's inspector. Check that "draw links" is on.

    2) Check in the unit's properties that "adjust to collider" and "adjust normals" are on and that you have the "adjust layermask" set and that the terrain is on that layer.
     
  5. dbryson

    dbryson

    Joined:
    Nov 9, 2009
    Posts:
    269
    Yeah, I know, but the checkbox for the connections does nothing when this is happening. Usually, it happens after you play the game and stop playing and go back to editing. The connections will be gone and checkbox is checked. Unchecking and checking does not fix it.

    I will check this.

    Thanks.
     
  6. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Please check if you are getting any error messages in the Unity console. The links should be visible in the editor after you get back form "play". I've just tested sample scene 2 and it works as expected.
     
  7. dbryson

    dbryson

    Joined:
    Nov 9, 2009
    Posts:
    269
    You were right about not having the layers setup correctly to have the units conform to the terrain. Working nicely now :)

    I have attached picture of Unity showing the node gizmo's with no connections and showing everything turned on. I wonder if this is a problem with the Advanced Terrain Shaders v2 package that I am using maybe? I am using a Unity terrain rather than an imported terrain mesh. I know you would need a way to reproduce this in order to fix it (if it is a bug).
     

    Attached Files:

  8. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    I've just tested and it still works fine with the Unity terrain. I am using the normal gizmo drawing fucntions of Unity to draw the lines and cubes, so if shaders where mesing with the lines then it would have done the same with the cubes.

    You are not getting any error messages? If there is an error then it can prevent the rest of script sfrom running.

    Did you make changes to the core code?

    Are you doing anything in your code where you might be unlinking nodes? If they are not linked then those links can't be drawn.
     

    Attached Files:

  9. dbryson

    dbryson

    Joined:
    Nov 9, 2009
    Posts:
    269
    Must be something in my project or something on my system.

    No, no error messages.

    I haven't made any code changes.

    I have not done anything in my code to unlink nodes. When this happens, all node links disappear, like they are just not being drawn. And, as I have said, disabling and then re-enabling the MapNav object restores the drawing of the links. Very weird.

    Anyway, not a big deal for me, as I can work around it.

    Thanks for your great support.
     
  10. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    I can have a look at the project if you want. Contact me via the pm system.
     
  11. jingato

    jingato

    Joined:
    Jun 23, 2010
    Posts:
    274
    Hi, I recently purchased this product and I have a quick question. Well....3 of them.

    1. How can I determine if a specific node is reachable by more than one tyletype? Say I have a unit that can travel of land and water. I thought doing this might do the trick

    Code (csharp):
    1. bool endIsReachable()
    2. {
    3.     TileNode[] path = map.GetPath(player.node, endNode, (TileNode.TileType.Normal  TileNode.TileType.Water));  
    4.     return (path != null);
    5. }
    but that returned true even when It could not be reached so I tried oring it instead and that returned false even when it could be reached.

    2. When I click on a node, my unit moves to that node if he can. If he can't he just stays where he is. Is it possible to have him move to the closest node possible when he can't reach the desired node with minimal effort or would I need to do the path navigation and calculation fro something like that myself?

    3. I want to show a dotted line between each node while in game. I am using with with Sprite Manager 2 so I'm assuming I would make a sprite of some sort between each node. How would you recommend to do this? I noticed that there are lines between each node already in the editor so you must have some code that does a similar process? Would you just go through every node and draw a sprite between each connecting node at the start of the level? Or do you have a built in function that would make this easier?

    Thanks...and great product!

    John
     
    Last edited: Oct 25, 2012
  12. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    1) GetPath does not take a mask but a TileNode.TileType. The getpath assumes that a unit can move over only one type while a tile can be of more than one typ, like air and water. Create a new TileType like "Hover" and assign that to the unit that can move over both water and land and mark tiles that are such with "Hover" since tiles can have more than one type.

    2) GetPath and the internal unit movement functions was not made for this since it borders on what you would do on your AI side of code. There is a version of GetPaththat soes not take a 3rd param (TileType). This will return the shortest path to the destination, ignoring obstacles. You can then run through this from the starting node and manually check where an obstacle is and make that your new target. You can either code a new movenent fucntion that makes use of this GetPath or call theexisting movement fucntion(s) with the end node to calculated in the previous step (note that GetPat hwould be called again to calc a path to this node, so a bit mroe overhead doing it this way).

    3) Not quite sure if you are refering to, but here goes an answer. If yo uare refering to the node links (the line syou see connecting the nodes in the editor) then those are just gizoms and can't be used for a release game. If you refer to the white node marker, those are textured obects like a plane or in the case of hex node, a plane in hexagon form.
     
  13. jingato

    jingato

    Joined:
    Jun 23, 2010
    Posts:
    274
    Sorry, I guess I didn't explain that too well. Alls I want to do is show a dotted line between each tile that is available at runtime. Like the image below. I was wondering if there's any way to to this easily out of the box


     
  14. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    I do not know how you will render the dotted line. I can only suggest you look into the line rendering code available on the wiki/forum, or use a plane with a dotted texture on it, or look into Unity's line renderer to see if that might be usefull.
     
  15. Linus

    Linus

    Joined:
    Feb 22, 2012
    Posts:
    111
    Enjoying the package so far,
    Was wondering what would be the best way to have the attack range marker only show if there is an enemy on the tile?
     
  16. Raspilicious

    Raspilicious

    Joined:
    Jun 21, 2012
    Posts:
    24
    I don't have code handy atm, but the way I worked out how to do this was to have a game object which you move to tiles that have enemies on them. Use checks to determine if the enemy is in your unit's attack range, then a dynamically resizing list/array of attack marks (fhink the sims green diamond, but a red one, that's what I used), and move one of those marks above every enemy in range (its transform.position).

    For mystery person who asked about "move close to a target" (im on phone and can't see ur post while I type this lol) you can order a unit to move further than its move range by showing the tiles (show means u can click em). The unit will move along a path to that tile, but will stop when it reaches its nax move range. It could be possible to make a function which moves a unit a long distance over multiple turns with one order using this method I think.
     
  17. Linus

    Linus

    Joined:
    Feb 22, 2012
    Posts:
    111
    So just give every enemy an attackable marker and turn it on if in range. Just scrap the built in radius marker.
    Another way, I think, would be to give each node a script link to any gameObject that is on them. And have the radiusMarker.cs check if there is an enemy on the tile. Hoped there was a simpler solution that I had missed.
     
  18. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Radius marker is something made for a specific purpose and should be used for that. It would be easier, as Raspilicious said, to just have single tile markers which you can move around (just like radius marker is moved around) to mark the targets that are in range. Heck, you could even use the tilenode markers for this, the ones that are used to show where you can move. Write something that enable the correct ones and tint them red.
     
  19. E1iTe

    E1iTe

    Joined:
    Aug 7, 2012
    Posts:
    47
    Hi Leslie, Thanks for all your help so far! i was wondering where to start looking to modify the Attack Radius code again to do the:

    X
    XXX
    X

    X
    X
    XXXXX
    X
    X

    Style markers instead of the default:

    XXX
    XXX
    XXX

    XXXX
    XXXX
    XXXX
    XXXX

    I know you answered it on your forum in the past but I was not able to access it again.
     
  20. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Here is what I said about it previously (in the other forum), let me know if anything is not clear ...

     
  21. Linus

    Linus

    Joined:
    Feb 22, 2012
    Posts:
    111
    Ok :)
    Thanks for the reply. Learning a lot from the package.
     
  22. CrucibleLab

    CrucibleLab

    Joined:
    May 29, 2012
    Posts:
    19
    Hello, M&N users!

    I have been working on adding a custom unit on a map. I can make it spawn on the map just fine but the problem is, I cannot seem to select it when the project is in 'Game' mode. I can select and move the standard unit that came with the asset with no problem. I should also mention that:

    * The reason why I ended up using a custom unit prefab (as opposed to re-using the out-of-box standard unit prefab) is because my custom unit consists of three moving parts (whereas the standard unit is just a single object) and, obviously, there's the parent-child relationship built in it.
    * I assigned all the standard scripts (i.e., Unit, SampleWeapon) to my custom unit prefab.
    * I added the Box Collider component to the custom unit prefab to ensure the raycast detection.

    Having said that, I am speculating the issue might have something to do with my custom object not sitting in the proper layer. I think Leslie made a quick reference to this in one of the tutorial videos he made available to the users but I think it was for the older version of M&N so it sort of lost me as to what exactly needs to be done for the object layers.

    Any tips/insights will be much appreciated!

    Owen
     
  23. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Layer 21 is the "Unit" layer used in the samples.

    Also be sure that the collider and Unit scripts are on the same object, meaning, the collider should not sit in some child object while the unit scrpt is on the parent. Yo uwil lsee an error message if tis is an issue though. I'm just thinking there might be sample code that try get the component from the selected object. which could fail.
     
  24. CrucibleLab

    CrucibleLab

    Joined:
    May 29, 2012
    Posts:
    19
    Leslie, I found the code that assigns the value 21 to unit layer in the TMNController script. But, I am still wondering where you assign the same value for the unit prefab. My assumption here is that the unit prefab has already been assigned the value since that's how the raycast function checks to see if the object you are attempting to control is in the layer that is predefined in the script. Perhaps, it is assigned via the Inspector panel?

    Thanks, Leslie!
     
  25. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
  26. CrucibleLab

    CrucibleLab

    Joined:
    May 29, 2012
    Posts:
    19
    Leslie, thanks for answering my previous question. I'm afraid I have another dumb question for you:

    One of the scenes that come with your asset has different types of battle units spawning on the same map. And the Land/Water units spawn, well, right on the surface whereas the Air units spawn well above the surface. Seems pretty straightforward.

    But, I am having a hard time trying to figure out what setting(s) actually control the positioning of each unit. In other words, what did you do to make the Land/Water units spawn right on the ground and make the Air units spawn midair? The initialization script doesn't seem to make the distinction between Land and Air units so I am feeling a bit puzzled here.

    Thanks for your time!
     
  27. VFe

    VFe

    Joined:
    Oct 18, 2012
    Posts:
    4
    Bought this, very nice library for the money.

    My only comment is from a customer perspective, it'd be nice if you could include some better documentation. Even just a "cheat sheet"(Just a list of all the classes/methods in the source, a one sentence description of them, and maybe an example of use) would be really helpful.

    I know I can just go through and read comments in the code, but having it all in a concise document imho is really helpful to people trying to learn how to use and extend it. The actual documentation included could use some formatting/layout improvement too.

    Just suggestions for adding some value, I certainly won't claim this didn't save me $35 of time =0
     
  28. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    The short answer, offset the art part of you unit any where you want it from the true pivot.

    Create a new scene scene and drag P1_Unit_Air and P1_Unit_Land into it to see how they differ. It will be good to position them at 0,0,0 with one of the units at x=0.6 so you can see them side by side.

    Notice how that both unit's pivots are at the bottom but yet the flying unit's art (body of the uit) is at y=0.5486734. When I move a unit from node to node I'm moving both flying and land units in the same manner, but because the "art" of the flying unit is offset from the ground it looks like it is flying/hovering. You will also notice that the art part of the unit is a child object of the actual unit object. This allows me to easily tweak where I want it without having to make changes in an art program and then re-export.

    When it comes to shooting at units you would not want to shoot at the pivot (whereever that might be) but at the actual body (art) of the unit and that is what the "Targeting Offset" proeprty is for in the properties of the unit. You basicalyl take the unit's position, add this offset and you know where to point a laser at or send a missile to.
     
  29. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    799
    Yay, another one on my list of my never ending questions. ;) Can nav points be moved freely after setup? That way the TBM&N package would be a great tool for irregularly shaped maps as well, like in a Risk-style game.
     
  30. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Yes, you can move the nodes around and they keep their connections with their "neighbouring" nodes - which you wil lsee by the connection line gizmos.
     
  31. CrucibleLab

    CrucibleLab

    Joined:
    May 29, 2012
    Posts:
    19
    Leslie, what you said makes perfect sense. I looked high and low for an answer (including Unity Answers forum) and no one's half as good as you in explaining the mechanics.

    Thanks!
     
  32. dsfds

    dsfds

    Joined:
    Aug 19, 2012
    Posts:
    16
    All of your example game objects are 1 x 1 tile. (If i am right)

    For example, a person takes 1 x 1 and a tank that takes 2 x 2 tiles and able to move around in map.

    How should the "SpawnUnit" handle it? And does the path finding work in this case?
    Or Could you give me any solution to solve this problem but not limiting all objects to be 1x1.
     
    Last edited: Nov 12, 2012
  33. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Yes, Map&Nav was created with 1x1 units in mind and there is no code that can check if a bigger unit can move through "tights"spaces. For example, there is no code that will know that a 2x2 unit can't move over a tile with pillars (r other units) on either side. Sorry, but this is not something I have an easy solution to.
     
  34. dsfds

    dsfds

    Joined:
    Aug 19, 2012
    Posts:
    16
    m. Lets take out the path finding part. is it still possible? Is it possible to have 4 tiles share the same object (a Tank).
    Any demo code would be great. Thanks
     
  35. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    You could have one object span more than one tile. Choose a pivot that is offset such that it will cover one tile properly then the other sides will be the "överlap" that covers other tiles.

    The spawn code will only set the one node that was chosen to spawn the unit over, so you would have to manually set the other nodes as occupied. Keep in mind that none of Map&Nav's code know that one object/unit can cover more than one node, so don;t make any assumptions there as it will cause bugs, especially with the build-in movement code.

    To know which other nodes to set wil ldepend on what you decide is the "main tile point". Let me try explain it like this ...
    0 0
    # 0

    each of the above 0 and # is a tile position with # where the pivot of the unit will be at and the unit overlapping where 0 is. So when you spawn this unit the # will be set as being occupied by the uit and now you need to manually set the 0 positions, which should be easy since you know a newly spawned unit will have overlap to tiles above and to the right. You could also extend this to support 90* rotated units since the # position always stay the same and 0 positions rotate around that, like...

    rotated clockwise, right, down, left (and then up would be the default position)
    # 0 .. 0 # .. 0 0
    0 0 .. 0 0 .. 0 #

    To do the needed calculations you will need to know the node's x/y or index position. The system was not made to work as a 2 dimansional array but if the nodes are all in order and numbered you can assume that node30 (named such) is 30th in the array and can work with that.

    So TileNode.idx would be what we looking for. Let's say it is 30, then
    For the "default" position you could use the following to find the other 3 nodes.
    the node to the right: idx= main_node.idx + 1;
    node above: idx= main_node.idx + Map.nodesXCount;
    node above and to right: idx= main_node.idx + Map.nodesXCount +1;

    and then for each you use the new idx values with map[idx], or map.nodes[idx]. Something like map[idx].unit.Add(the_big_unit); to link with tne unit.

    Similarly you can calculate the idx for the 3 nodes when the unit is rotated; and watch out for the case where the unit is spawned against an edge.
     
  36. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    799
    This might be a brute force approach, but what about a second tile map with 2x2 sized tiles instead of 1x1 layered on top of the first one? You would still need to somehow communicate the unit positions between these two layers of course so 1x1 and 2x2 units don't occupy the same space of course, but that's an issue I don't have a good idea for right now.... :D

    [edit] On second thought (read: Google search) there are some interesting ideas in this thread: http://www.gamedev.net/topic/37929-pathfinding-for-large-units/ - maybe something to introduce in a future version?
     
    Last edited: Nov 13, 2012
  37. miniduck

    miniduck

    Joined:
    Sep 27, 2012
    Posts:
    117
    Hi Leslie
    Apologies if this has been answered already but here it goes.
    Does it support map creation, deletion and editing at runtime?
     
  38. dsfds

    dsfds

    Joined:
    Aug 19, 2012
    Posts:
    16
    Leslie Young:
    Thank you for your suggestion and they are really helpful. I will take that and try.

    Q1)
    In your example, when you click on a car,the car will show that radius square thing to show the legal moves of the car.
    Do you think i can take advantage of it? I want to check if all 4 squares are legal to put a new tank starting from the #.
    (PS: if you dont remember what # is, see your last comment)

    Q2)
    map[idx].unit.Add(the_big_unit);
    Is there anyway to turn off the node in that square in path finding too? how to do that in code?
     
  39. dsfds

    dsfds

    Joined:
    Aug 19, 2012
    Posts:
    16
    Ya it is pretty brute force, however, 2x2 sized tiles does not scale. For example, lets say next time if my artist wants to put a train in it, which takes 2x1 tiles or 3x2 tiles. It wouldn't work again.
     
  40. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    799
    This sounds even better and is well-explained as well. :)

    http://aigamedev.com/open/article/clearance-based-pathfinding/


    Yeah, it just was the first thing that came to mind. Though a non-square unit introduces some additional problems when it comes to rotating and turning of course.
     
    Last edited: Nov 13, 2012
  41. dsfds

    dsfds

    Joined:
    Aug 19, 2012
    Posts:
    16
    Your link is pretty interesting. I will think of it when i need to re implement path-finding. Thanks ;)
     
  42. c-Row

    c-Row

    Joined:
    Nov 10, 2009
    Posts:
    799
    Unfortunately it doesn't work for non-square units, but I already dropped the author a mail on the subject. :)
     
  43. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Very cool links, thanks ;)
     
  44. dsfds

    dsfds

    Joined:
    Aug 19, 2012
    Posts:
    16

    I still have 2 questions did not get answered. hope you didn't missed.
     
  45. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    Sorry, totally missed 'em...

    >> Does it support map creation, deletion and editing at runtime
    Yes, the main fucntions are all in the runtime side and the editor scripts calls into the runtime scripts to ask 'em to do things like make the map.

    >> In your example, when you click on a car,the car will show that radius square thing to show the legal moves of the car.
    >> Do you think i can take advantage of it? I want to check if all 4 squares are legal to put a new tank starting from the #.
    >> (PS: if you dont remember what # is, see your last comment)
    The best way would be to do it the way I explained. I suppose you coudl also use a something similar to what the radius marker is doing to check if there is a unit (or to even check for walls or other objects). It is just casting rays to check what is sitting on the tile, if anything.

    >> map[idx].unit.Add(the_big_unit);
    >> Is there anyway to turn off the node in that square in path finding too? how to do that in code?
    Yes, check out the function at line 299 of the TileNode.cs script; TileNide.SetLinkState(TileNode withNode, bool on) or better yet, the one on line 330, SetLinkStateWithAll(bool on) which will change the link state with all the node's neighbours to on or off.
     
  46. E1iTe

    E1iTe

    Joined:
    Aug 7, 2012
    Posts:
    47
    Thanks again Leslie for all of your great help! I believe i have one final question if you can be so kind as to help me out. I was wondering how you projected the attack radius markers onto the field? Im trying to do the same with the movement markers but can't figure it out. i'm using a terrain as a floor with variable heights now instead of blocks so I was wondering if it is easy to project the movement tiles as decals or something onto the terrain.

    Thanks in advance!!
     
  47. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    The markers are simple planes with the correct texture on. The problem wit this is that the markers wil lstick through uneven terrain, look closely at the movement markers of sample "sample02_variable_height" to see this hapen. The only solution for this that I know of is to use projectors. http://docs.unity3d.com/Documentation/Components/class-Projector.html
     
  48. E1iTe

    E1iTe

    Joined:
    Aug 7, 2012
    Posts:
    47
    Thanks for the response! do you think projectors would be a good idea to use and still get the same functionality or should i just continue to use what's currently there? Do you know where i can easily edit it (or code example) to try a projector instead or would it be very involved to switch to something like that?
     
  49. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,053
    To set 'em up and use them should be easy. You will start by creating a node prefab that incldues the projector rather than a textured plane. In code you need to go through TileNode and check for areas where visiblity of the markers are set; for example the OnHover, Hide, and various Show functions and then change it such that it can enable/disable the projector that is now part of that tile.
    Scripting Reference
    The Component
     
    Last edited: Nov 15, 2012
  50. E1iTe

    E1iTe

    Joined:
    Aug 7, 2012
    Posts:
    47
    Ok I will see what I can come up with. You've been a great help with my project thanks! If you do get some time i would be very greatful if you had a code example but no worries if you can't. I'm just not the greatest programmer in C# but i'm not too bad. Thanks again!
     
unityunity