Search Unity

Tile Based Map Nav

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

  1. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Yes, Marker Nodes ( the blue tileNodes) are the ones on the Radius Marker and they have the "Default" Layer "built in 0 " not "tile".The last code that i have posted has nothing to do with the Markers Node.It´s attached to another gameobject "raycast manger". The latter has a public Transform which is the "Cube" (rayCasterObject) For testing purposes only.

    $Cube Ray cast.PNG

    And as you see the Raycast work fine. the "if (hit.transform.gameObject.layer == Layer1)" with (Layer1 = LayerMask.NameToLayer("tile") ) return a true if the raycast hit a TileNode (the white tileNode / layer = 20) so we get "object down detected"

    But using the Marker Nodes (the blue tileNodes) as Raycaster Source seem to be problematic.Maybe because of the foreach :confused: I really don't get it but i have to fix this. It´s very very important for the development of my Game.
     
  2. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    The main problem was that the "parent" of a group of markers was set inactive and with the new way Unity 4's SetActive work that cause the problem that prevented the child objects from being shown. Anyway, here's code that works. I've tested it.

    Code (csharp):
    1.  
    2. public class RadiusMarker : MonoBehaviour
    3. {
    4.     public int tileLayerMask = 0;
    5.  
    6.     void Start()
    7.     {
    8.         HideAll();
    9.         tileLayerMask = 1 << LayerMask.NameToLayer("Tile"); // change to whatever your Tiles are named
    10.     }
    11.    
    12.     public void Show(TileNode centerNode, Vector3 pos, int radius, bool adaptToTileHeight = false)
    13.     {
    14.         HideAll();
    15.  
    16.         // 0 or less means to show nothing, so return now
    17.         if (radius <= 0) return;
    18.  
    19.         // check if within limit
    20.         if (radius > markerNodes.Length) radius = markerNodes.Length;
    21.  
    22.         // move it to given position
    23.         transform.position = pos;
    24.  
    25.         if (adaptToTileHeight || this.adaptToTileHeight) UpdateNodeHeight(radius, false);
    26.  
    27.         // turn on the tile nodes on the map so that I can do raycasts against them
    28.         centerNode.Show(true);
    29.         centerNode.ShowNeighbours(radius, true);
    30.  
    31.         for (int i = 0; i < radius; i++)
    32.         {
    33.             // important that this is done so that the "parent" is active, but this wil lalso
    34.             // make active all the children so they will have to be set inactive as needed
    35.             markerNodes[i].SetActive(true);
    36.             for (int j = 0; j < markerNodes[i].transform.childCount; j++)
    37.             {
    38.                 Transform t = markerNodes[i].transform.GetChild(j);
    39.                 Vector3 p = t.position;
    40.                 p.y += 1;
    41.                 if (false == Physics.Raycast(p, -Vector3.up, 10f, tileLayerMask))
    42.                 {   // since all markers are active i only have to set inactive as needed
    43.                     t.gameObject.SetActive(false);
    44.                 }
    45.             }
    46.         }
    47.  
    48.         // turn off the tile nodes, done with them
    49.         centerNode.Show(false);
    50.         centerNode.ShowNeighbours(radius, false);
    51.     }
    52.    
    53.     ...
    54.  
    It will also be a good idea to change the order in which functions are called. First make the call to show the marker and then the call to show tile nodes (if that is what you want). The reason is, the marker will show and hide nodes and thus mess up what you want shown if you show your nodes before calling the marker to show. Something like this from the example code ...

    Code (csharp):
    1.  
    2. selectedUnit = unit;
    3.  
    4. // move selector to the clicked unit to indicate it's selection
    5. selectionMarker.Show(go.transform);
    6.  
    7. // show how far this unit can attack at, if unit did not attack yet this turn
    8. if (combatOn) attackRangeMarker.ShowOutline(selectedUnit.transform.position, selectedUnit.attackRange);
    9.  
    10. // show how far this unit can attack at, if unit did not attack yet this turn
    11. if (!selectedUnit.didAttack  combatOn)
    12. {
    13.     attackRangeMarker.Show(selectedUnit.node, selectedUnit.transform.position, selectedUnit.attackRange);
    14. }
    15.  
    16. // show the nodes that this unit can move to
    17. selectedUnit.node.ShowNeighbours(selectedUnit.currMoves, selectedUnit.tileLevel, true, true);
    18.  
     
  3. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Well Sir it works like a charm :) I really appreciate the time you took to help me and thank you very much for the great support too.

    Notice : works only after changing "Tile" to "tile" in the "tileLayerMask" . Now RadiusMarker is a robust script :cool:

    Edit :

    for those who need this too :

    change in "RadiusMarker.Show" this codesegement from :

    Code (csharp):
    1. if (false == Physics.Raycast(p, -Vector3.up, 2f, tileLayerMask))
    2.                 {   // since all markers are active i only have to set inactive as needed
    3.  
    4.                     t.gameObject.SetActive(false);
    5.                 }
    to :

    Code (csharp):
    1.   if (false == Physics.Raycast(p, -Vector3.up, 2f, tileLayerMask))
    2.                 {   // since all markers are active i only have to set inactive as needed
    3.  
    4.                     t.gameObject.SetActive(false);
    5.                 }
    6.                 else
    7.                 {
    8.                     t.gameObject.SetActive(true);
    9.                 }
     
    Last edited: Aug 7, 2013
  4. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    Hi, there are a lot of pages here, so forgive me if this is already asked.

    I am trying to build a rogue like. I am using primarily Playmaker and 2D Toolkit, but I can mess around with commented code.

    I have been having a great deal of difficulty creating a procedurally generated map (40x40), the tiles of which I can switch out as I go.

    For instance, I want to run a nested loop to create a grid, but then be able to change any particular square into any particular terrain or what not.

    Will Map and Nav let me do that?

    Thanks,
    -Luke
     
  5. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    Perhaps I should clarify more. I'm looking to use a room gen algorithm I found over at roguebasin. The general idea is that I would make a 40x40 grid wall tiles, all marked as impassable, and then I "dig" out rooms by changing individual tiles in the grid into floor or door tiles, etc.

    Each grid space also needs to be able to contain one mob occupant and one item occupant simultaneously. How far can Map and Nav get me?
     
  6. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    Map&Nav does not handle anything graphical. It is this invisible grid of nodes that can be used to move stuff around and find out who is the neighbour(s) of a specified node, and such.

    [edit]
    >> contain one mob occupant and one item occupant simultaneously
    This can be done since it would be similar to, one flying and one land unit occupying the same tile.

    Have a look at the vids I've linked in the first post. They show about everything that you can do with this out of the box.
     
    Last edited: Aug 6, 2013
  7. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    Thanks Leslie,

    I bought Map and Nav last night and I'm very pleased with my purchase. The code is well commented and the examples are really helpful to me.
    I think I'll be able to accomplish what I need with this.
     
  8. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    Hi there,

    I'm trying to figure out how to attach prefab planes onto tile node at mapnav generation.

    For instance I have a floor plane with a cobblestone material which fits perfectly over the nodes so as to create a seamless floor.

    Currently, I am making a map and then manually place prefabs at the correct coordinates to cover the nodes.

    Seems like a lot of work, so I'm sure there must be some way to do it automatically.

    Can you offer any advice or point me to an example I've missed? There are lots of examples and it's taking me some time to get my head around everything at once.

    Thanks!
    -Luke
     
  9. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    If I understand you correctly then ...
    Map&Nav will not be able to auto place art related things (like tiles) for you. It works the other way around, you create your environment and then throw a map&nav onto it and use the mapnav tools so it can auto-configure its nodes to be of various types like, water, land, wall, etc.
     
  10. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    Thanks I think I understand now. I was hoping I could child a prefab tile to each node object as it was created, then later change the material at runtime by getting the node ID or something.

    This will still save me tons of time, so I'm still very glad I bought your system. :)
     
  11. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    perhaps if you make a new Node Prefab which includes the child?
    Then at runtime you look at what the node is set to (its type) and make changes to the child that is in it.

    [edit] this will allow you to generate a mapnav with all the nodes having children then. no more manual prefab placing.
     
  12. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    I had considered that and I think that would work well. What I've decided in the meantime is to use it as intended, but make a number of smaller 10x10 grids, and then randomly choose from a list and arrange them randomly.

    I am currently looking at your scene on linking maps, but I haven't quite gotten my head around it yet.
     
  13. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    is it possible to link two separate navmaps together through the code or does it have to be done in the editor?
     
  14. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    I found the extension that connects maps at runtime, I'm just not at all sure how to use it. Am I supposed to inject it into a different piece of code?
     
  15. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    You will use TNEForcedLink. The sample that looks like a room (dungeon) uses this to link two floors which you will see is separated.

    You can use this at runtime. Simply place TNEForcedLink onto the gameObect of one Node and then use LinkWith() to link with other node(s), which includes nodes from other maps.

    Here is the editor code that uses it to link up nodes. As you will see, it gives each node that component and then cross link everything. So both nodes that must link together need this component and then you call LinkWith() to link with the other nodes to the one that just received the component.

    [edit] Something else to look out for it that if you do this at runtime then the nodes' neighbours will not be updated (TileNode.nodeLinks). You will probably have to do this manually. MapNav.LinkNodes() runs at Start() and sets up the links then, but it can be a low process so you do not want it running after each time you add a forced link . .except if you can do the whole setup and then call it; else go to MapNav line 447 and see how forced links are checked and added to nodeLinks of a node.

    Code (csharp):
    1.  
    2. private void CreateLinkBetweenSelected()
    3. {
    4.     // get list of selected nodes
    5.     List<TileNode> nodes = new List<TileNode>();
    6.     foreach (GameObject go in Selection.gameObjects)
    7.     {
    8.         TileNode n = go.GetComponent<TileNode>();
    9.         if (n != null) nodes.Add(n);
    10.     }
    11.  
    12.     // now update links between these nodes
    13.     foreach (TileNode n in nodes)
    14.     {
    15.         TNEForcedLink ls = n.gameObject.GetComponent<TNEForcedLink>();
    16.         if (ls == null) ls = n.gameObject.AddComponent<TNEForcedLink>();
    17.  
    18.         // set link state with all other selected nodes
    19.         foreach (TileNode n2 in nodes)
    20.         {
    21.             if (n2 != n)
    22.             {
    23.                 ls.LinkWith(n2);
    24.             }
    25.         }
    26.     }
    27. }
    28.  
     
    Last edited: Aug 8, 2013
  16. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    Excellent thanks,

    I'll start working on this. :)

    As for the speed, the idea would be to preconstruct a number of 10X10 tiles, connect them randomly into a 50x50 grid, and do this only once each time a level is generated.
     
    Last edited: Aug 9, 2013
  17. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    I think I may have found a simpler solution.

    As you suggested previously, I've created a new node, with a prefab plane above it. So when I generate a map nav, all the tiles are aleady drawn.

    What remains now is to iterate through each node and change the material and variables on each tile prefab to get a randomized dungeon.

    So I'm currently looking for the part in your code where you iterate through all the tiles.
     
  18. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    MapNav.Start calls LinkNodes(); That is where I run through them all and create the links between them.
     
  19. Hmtinc

    Hmtinc

    Joined:
    Aug 11, 2013
    Posts:
    6
    I setup my Map on a smaller scale , but when I scaled everything up by 20 (including the unit size) the pre set zoom values were too low so you can;t really see anything . I tried adjusting the min distance and max distance values in the camera orbit script , but nothing seems to be changing . Is there something else i have to change inorder to zoom out further ?
     
  20. LukeJacobs

    LukeJacobs

    Joined:
    Jun 26, 2013
    Posts:
    11
    First off, Thanks for your patience and help so far.

    I'm integrating Map and Nav with Playmaker, and it's going all right.

    I can use playmaker to set properties on scripts, but the property has to be exposed in the inspector.

    While I see that the mask type is available in the inspector, the Playmaker Set Property action, requires me to call a method and pass a parameter.

    What I would like to do, is write a method in tilenode.cs that will allow me to change the mask type by passing an int.

    I've looked and I haven't yet found a method for doing this,

    Is there one that I'm missing? Failing that, is there any other way to change a node's mask type after the mapnav has been created?
     
  21. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    Setting Distance and Max Distance is all you should have to do. Of course, Min Distance should be the smaller number. Did you try big enough number, like 100 rather than 30?
     
  22. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    This can be done during edit time and runtime.
    the_tile.tileTypeMask = TileType.Normal;

    If passing an int then simply...
    the_tile.tileTypeMask = (TileType.Normal)some_int; // int should ofcourse be one of the int values the TileType related to
     
  23. Hmtinc

    Hmtinc

    Joined:
    Aug 11, 2013
    Posts:
    6
    Ok So I fixed the zoom issue by using more larger values . Now that i fixed the zoom issues i have 2 questions .
    1. I Created some new units and was wondering how i can get the new units to work with the sample game script ?
    2. The WASD keys allow for the user to move the camera around . but there is no lock on the camera to limit it to the map , so how would i lock the camera to the borders of the map . I am not that great with C# so i wrote some clamp code in unityscript and converted it to c# (Code below) , but it doesn't seem to work .
    Code (csharp):
    1. // -------------- Camera Clamp Code  ------------------------------------------
    2.  
    3.  
    4.  
    5.  float minPosition = -14.0f; // left border z
    6.  
    7.  float maxPosition  = 66.0f; //  right border z
    8.  
    9.  float minPositionx  = -8.75f; // left border x
    10.  
    11.  float maxPositionx  = 76.7f; //  right border x
    12.  
    13.  
    14. void  Update (){
    15.  
    16.     transform.position.z = Mathf.Clamp(transform.position.z, minPositionz, maxPositionz);
    17.     transform.position.x = Mathf.Clamp(transform.position.x, minPositionx, maxPoositionx);
    18. }
    19. // ------------------ End of Clamp Code ----------------------------------------
     
  24. keyboardcowboy

    keyboardcowboy

    Joined:
    Feb 8, 2012
    Posts:
    75
    Just picked up this package last night. I was wondering if any owners (or Leslie) has setup a system to switch from first-person real-time movement/exploration mode to using this system for the turn-based battle mode?

    I figure if someone else has already has something up and running, why re-invent the wheel :)
     
  25. Hmtinc

    Hmtinc

    Joined:
    Aug 11, 2013
    Posts:
    6
    From what I see you would have to write your own script to manage turns between two players , but there is a basic implementation of turns in the sample game scripts $Screen Shot 2013-08-15 at 1.26.41 PM.jpg
     

    Attached Files:

    Last edited: Aug 15, 2013
  26. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    Have a look at the prefabs created for the samples, for example the prefabs in Assets\Tile Based Map and Nav\Prefabs\units\
    If you open sample01 and click on GAME_MAIN_sample1 you wil lsee in the inspector "unit fabs". This is how I tell it about the units used in that example. The samples all differ in some way form each other so just have look at the various objects in the scenes and what unit prefabs are referred to.


    Did you put that code in the correct script? You will notice that the Update() function in CameraMove.cs is what handles the movement. You probably want to put your clamping code at around line 40, just before the if() test
     
  27. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Hi Leslie,
    I have some difficulty doing an Aoe/Aura Targeting System and i hope you can help me find a Solution :roll:

    So first i created a simple fonction for single Target purposes :

    Code (csharp):
    1. private void updateTargetUnit(GameObject go)
    2.     {
    3.         Unit unit = go.GetComponent<Unit>();
    4.  
    5.         targetedUnit = unit; // targetedUnit is already declared as  : public Unit targetedUnit = null;
    6.  
    7.     }
    and i´m calling it in another function that i have made for hovering over Navi Units in my GameController :

    Code (csharp):
    1.  protected override void OnNaviUnitHover(GameObject go)
    2.     {
    3.         base.OnNaviUnitHover(go); // using the same principe of hovering over tilenodes (raycast test)
    4.                                           // but this time we are looking for Units.
    5.             if (go != null)
    6.             {
    7.                 updateTargetUnit(go);
    8.             }
    9.             else
    10.             {
    11.                 targetedUnit = null;
    12.             }
    13.         }
    14.     }
    15.  
    here is an exemple of a single target Spell to get a better idea of how my Spell-System work ( single target spells are working fine by the way )

    Code (csharp):
    1.  public class FireBlast : BaseAbility
    2.     {
    3.         public FireBlast ()
    4.         {
    5.          this.Name = "Hadoken";
    6.          this.CastRange = 4;
    7.         }
    8.  
    9.         // initialisation
    10.         public FireBlast (Unit myUnitCaster)
    11.             : this()
    12.         {
    13.             this.UnitCaster = myUnitCaster;
    14.         }
    15.  
    16.         public override void DoEffect(Unit target)
    17.         {
    18.             if (UnitCaster.node.IsInRange(target.node,CastRange)
    19.             applyDamage(target);
    20.         }
    21.    }
    and to cast the selected spell on a target i simply call "selectedSpell.DoEffect(targetedUnit)".

    What i´m trying to achieve now is to target a group of units. I looked for a similare function to TileNode.IsInRange() made for Units (not TileNodes) so that i can look for all units in Range and apply the DoEffect() to each one of them but i didn´t found it.

    i was thinking about adding something like this into my GameController :

    Code (csharp):
    1.   public List<Unit> targetGroup = null;
    2.  
    3.    private void updateTargetGroup(List<GameObject> go)
    4.     {
    5.         foreach (GameObject test in go)
    6.         {
    7.             Unit unit = test.GetComponent<Unit>();
    8.         }
    9.  
    10.     etc...........
    11.     }
    then repeating the same process of hovering over units and casting a raycast regarding Aoe-spells because Aura effects doesn´t require a hover check etc etc etc... but i think it will become too complicated this way and nearly impossible (very bad performance).

    I´m now stuck on this problem for a week now and i would greatly appreciate it if you can do something about it.

    Many thanks in advance for your help.
     
  28. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    Do a TileNode.GetAllInRange() from the "center" one, which returns a list of nodes. Now you can run through this and access node.units to find out what units are standing on the node and decide what to do with that unit.
     
  29. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Ok sounds legit.I ll follow your suggestion.But what´s the difference between TileNode.GetAllInRange() and TileNode.GetAllInRangeWithUnits() .When to use each one of them ??
     
  30. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    TileNode.GetAllInRangeWithUnits might be better since it will return only those nodes with units on 'em. The other one return all tiles in certain radius.,
     
  31. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    I was expecting that :D Ok i´ll try to figure out a solution.
     
  32. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    Ok i finished the Aoe targetting-System so far but i still having some issues.

    The first issue is : how to get the unit in the center-node of the range? As far as i know the TileNode.GetAllInRangeWithUnits() method return a list of nodes (In Range) except the middle one.So How can i include that one to the returned List?

    The second issue : how to display the middle Marker-Node on the radiusmarker? As default radiusmarker hide the middle markerNode.
     
  33. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    Simply add it to the returned list since you know what it is. returned_list.Add(the_center_one);

    This marker was created as something that is used with a friendly unit at the center. You will have to modify its code and graphics to do what you need.
     
  34. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    I feel stupid about the first one it´s really simple. As regards the second issue, i think the only way is to edit RadiusMarker creation-tool so i can also instantiate the middle marker-node during the marker creation process and so on.
     
  35. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    The marker object is created inside RadiusMarker.cs via CreateMarker()
     
  36. bakkoto

    bakkoto

    Joined:
    Aug 5, 2012
    Posts:
    24
    ok it´s done and works fine.Here are some modifications that i have done. Just in case of needed ;)

    Code (csharp):
    1. public class RadiusMarker : MonoBehaviour
    2. {
    3.     public bool addCenter = false;
    4.  
    5.     public static void CreateMarker(GameObject markerFab, MapNav.TilesLayout markerLayout, float markerSpacing, float markerSize, int markerRadius, bool adaptToTileHeight, bool addCenter, int tileMask)
    6.     {
    7.         marker.addCenter = addCenter;
    8.     }
    9.  
    10.     //you can do the same for Squar4Nodes and Squar8Nodes
    11.     private static void CreateHexNodes(GameObject markerFab, RadiusMarker marker, MapNav.TilesLayout markerLayout, float markerSpacing, float markerSize, int markerRadius)
    12.     {
    13.         GameObject go;
    14.         marker.markerNodes = new GameObject[markerRadius];
    15.  
    16.         float xOffs = markerSpacing * 0.50f * Mathf.Sqrt(3f);
    17.         float yOffs = markerSpacing * 0.75f;
    18.         float offs = xOffs * 0.5f;
    19.  
    20.         if (marker.addCenter)
    21.         {
    22.             GameObject middleParent = new GameObject();
    23.             middleParent.name = "Center";
    24.             middleParent.transform.position = marker.transform.position + new Vector3(0f, 0.1f, 0f);
    25.             middleParent.transform.parent = marker.transform;
    26.  
    27.             go = (GameObject)GameObject.Instantiate(markerFab);
    28.             go.transform.parent = middleParent.transform;
    29.             go.transform.localScale = new Vector3(markerSize, markerSize, markerSize);
    30.             go.transform.localPosition = new Vector3(0f, 0f, 0f);
    31.         }
    32.     }
    33.  
    34. }
    35.  
    and also :

    Code (csharp):
    1. public class MarkerCreateWindow : EditorWindow
    2. {
    3.     private bool addCenter = false;
    4.  
    5.     void OnGUI()
    6.     {
    7.         EditorGUILayout.Space();
    8.         addCenter = EditorGUILayout.Toggle("Add the Center Node", addCenter);
    9.         GUI.enabled = adaptToTileHeight;
    10.         tilesMask = EditorGUILayout.LayerField("Tiles Layer", tilesMask);
    11.         GUI.enabled = true;
    12.  
    13.         EditorGUILayout.Space();
    14.         if (GUILayout.Button("Create Marker"))
    15.         {
    16.             RadiusMarker.CreateMarker(markerFab, (MapNav.TilesLayout)markerLayout, markerSpacing, markerSize, markerRadius, adaptToTileHeight, addCenter, tilesMask);
    17.             Close();
    18.         }
    19.      }
    20. }
    21.  
    Many thanks for your help and support Leslie and as always you are really awesome :cool:
     
  37. bakkoto

    bakkoto

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

    can i return a one direction Path with the "Map.GetPath()" ? Or does your Package already contain a suitable method for this?

    One Direction Path exemples :

    $Unbenannt.PNG
     
  38. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    GetPath() does A* to find the path. There is not anything that can return a path in a certain direction. If there are no obstacles then GetPath should find the paths along the lines as you indicated if you specify the target node where the arrow ends.
     
  39. burzum793

    burzum793

    Joined:
    Jun 25, 2013
    Posts:
    18
    When I try run the sample04 scene and enable Combat On I get exceptions. I have not modified the script yet in any way.

    Should the examples not be error free?

    Edit:

    After I figured out that I have to use the RadiusMarker script and set it in the GameController the previous exceptions were gone but now I'm getting:

    Do you have a git repository I could fork and contribute back to?

     
    Last edited: Sep 19, 2013
  40. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    There are no errors when I run the sample 4. You should not change any of the settings (I see you ticked 3 checkboxes in screenshot). The options there are to configure for samples that supports those features. This specific sample was to show something where you have more walls on the map area and also how to handle a situation where you have a door (you will see there is a door in this sample which will open if you click on it).
     
  41. burzum793

    burzum793

    Joined:
    Jun 25, 2013
    Posts:
    18
    Yes... I'm sorry, my fault. I thought you could modify the behaviour of that example. I've checked now level sample01 which is pretty much what I was looking for and trying to archive, this will give me a good start.

    But I have a conceptional question now: What is the best way to create a player spawn? I would like other people to be able to build levels without much programming experience so the best would be if they could just drop a prefab in and assign it somehow to a node. Any guide on that? I'm not asking for code but for an idea how to do this the best in unity. Specially if I want to spawn on two nav maps.

    I've checked the code of the GameControlle, NavUnit and think I understand how the random spawn works but I have right now no idea how to define that I want to spawn unit X on nav mesh A and unit Y on grid B within the same controller. Looks like this requires some refactoring.
     
    Last edited: Sep 19, 2013
  42. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    I assume when someone edit the map in-game he would have to place tiles according to the node spacing and you would probably use the nodes to figure out where the position is that a tile can be placed when he moves the tile around (snap to node/grid). Since you know the node you could then easily save its name in the spawn point object and a simple GameObject.Find() should have you sorted when loading the map data and trying to find that node again.

    If you are talking about creating additional editor tools to help other devs in the team. Well, a ray-cast would probably best to see over which node he placed the spawn point. Or perhaps you can add additional properties to nodes to indicate them as spawn points.
     
    Last edited: Sep 19, 2013
  43. burzum793

    burzum793

    Joined:
    Jun 25, 2013
    Posts:
    18
    Yes, I already thought about adding it as property to the node. But the current GameController class just manages one NavMap or will it get the 2nd NavMap as well when I connect them? I saw I can connect them in the examples but haven't yet tried it with my own scene and changes.
     
  44. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    With the link(s) setup between nodes of two maps they would should look like normal neighbours of each other, but yes, it can become tricky to know on which map you are working. The linking is really only useful with the path finder and the nodes finding other nodes within a radius. you won't suddenly be able to access the 2nd map's nodes as if they where in the array of the 1st one :(
     
  45. burzum793

    burzum793

    Joined:
    Jun 25, 2013
    Posts:
    18
    So the link can be seen as a helper for the transition from one to another map? I guess when the unit moves "across" the link it get its map instance updated or something. I guess I could modify my game controller and have a list of maps.

    Sorry for the lots of probably stupid questions, I'm familiar with programming but not very much with unity yet.
     
  46. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    If I recall, the sample unit do not save what map it is in but only what node, cause most work is done by the nodes class. Nodes do know who their owning maps are so I guess you have this link available through the node.
     
  47. Chris_E

    Chris_E

    Joined:
    Jul 10, 2012
    Posts:
    32
    Hi! I tried reading through all of this, but only read about 10 pages so sorry if this was asked before.

    Is there any way to add D&D style movement to this package: Meaning diagonal movement will cost 1.5x straight movement? Meaning that moving up and to the left two squares will cost 3 movement instead of 2?
     
  48. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    No, the build in path finder does not work like that.
     
  49. burzum793

    burzum793

    Joined:
    Jun 25, 2013
    Posts:
    18
    Should it not be possible to cast a ray in 45° in all 4 directions and detect the nodes that were hit? Well, this only work when there is no height difference and any other obstacles.
     
  50. Leslie-Young

    Leslie-Young

    Joined:
    Dec 24, 2008
    Posts:
    1,148
    It would be better to look at the position of the neighbouring node in the node list.
    They are placed in there in a specific order so you can make assumptions about what are diagonal.

    MapNav.nodes is the array of all nodes.
    MapNav.LinkNodes() (line 307) is where this list is created and nodes linked to each other.
    Line 403 is where the 8-square layout is created (I assume you use this seeing as you want diagonal movement)

    TileNode.nodeLinks are the links of the node with its neighbours. If you look at the LinkNodes() code you will see that 4,5,6, and 7 are the nodes diagonal to the one being looked at.

    n.nodeLinks[0] - link with previous node
    n.nodeLinks[1] - link with next node
    n.nodeLinks[2] - prev row, same column
    n.nodeLinks[3] - next row, same column
    n.nodeLinks[4] - prev row, prev column - a diagonal
    n.nodeLinks[5] - prev row, prev column - a diagonal
    n.nodeLinks[6] - prev row, next column - a diagonal
    n.nodeLinks[7] - prev row, next column - a diagonal

    MapNav.GetPath(...) (line 112) can now be modified to take this into account when calculating the path.