Search Unity

Tile based game data structure

Discussion in '2D' started by nantoaqui, Nov 6, 2019.

  1. nantoaqui

    nantoaqui

    Joined:
    Oct 1, 2014
    Posts:
    42
    Hello!

    I've been working on a top down 2d game and the character moves freely around the map. The map is drawn using unity's tile maps but it currently doesn't support NavMesh.

    How would you model the data structure for such a game in order to implement pathfinding, astar, etc.

    As far I understood one could go with this approach:

    Tile {
    sprite
    walkable
    }

    Board {
    width
    height
    tiles: Tile[]
    }

    In a board of 5x5 there will be a sprite rendered for each tile. But here comes the problem:

    The player is at position (1,1). Now it moves to the right side (2,1). This will mean that the player is moved immediately from one tile to another. So, we could make the player move pixel by pixel. How would you translate this back to the grid position?

    If player moves pixel by pixel and is at position (1.5,1), should we take into account the current direction in order to predict collisions?

    I'm kind lost in this subject, i would love if you could share some thoughts on it, articles, videos, books, etc.

    Thanks!
     
  2. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @nantoaqui

    Look into tile or grid based movement. There are several tutorials and articles available. Those don't even need to be Unity specific as this is a generic concept for movement.

    The core idea is:
    - Store player / npc position as tile position (player at 1,1)
    - Take input when player is not transitioning from tile to tile
    - If player moves left, target position is position.x-1, position.y
    - Store this to targetPosition and mark player to be transitioning / busy
    - While player is not at targetPosition, move player torwards target
    - When targetPosition is reached, mark player again to be able to accept input

    You will also have to check your board data for free directions, so if you are moving left, check if tile to left in your data is walkable. Only then allow player to start moving.

    And Unity has pretty nice tutorial on tile based movement:
    https://learn.unity.com/project/2d-roguelike-tutorial
     
  3. nantoaqui

    nantoaqui

    Joined:
    Oct 1, 2014
    Posts:
    42
    thanks @eses, it helped to come up with new ideas!

    I would like to have the player moving freely, like zelda from snes. So maybe I could have the player position stored in a different place using floating points instead of integer and somehow map it back to the tile cell.

    +---+----+
    | | |
    +---+----+
    | | |
    +--P-----+

    P is the player and I would like to render it in between the tiles.
     
  4. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @nantoaqui

    I'm not quite sure what you want based on that ASCII art, but if you want to store player position in floats, then you can also round that position to int position, so you can get the tile position for character.

    See C# math class...Round, Ceil Floor can be useful in this case.

    https://docs.unity3d.com/ScriptReference/Mathf.html

    Edit - see this. Add this to some cube, and move it in front view (so that you can see the viewport grid) and compare the values:

    Code (CSharp):
    1. public class RoundCoordinatesTest : MonoBehaviour
    2. {
    3.     // For testing shows float position of attached transform
    4.     public Vector2 position;
    5.     // shows rounded position = tile position
    6.     public Vector2Int positionInt;
    7.  
    8.     void Update()
    9.     {
    10.         position = transform.position;
    11.         positionInt = new Vector2Int(Mathf.FloorToInt(position.x), Mathf.FloorToInt(position.y));
    12.     }
    13. }
    14.  
     
    Last edited: Nov 6, 2019