Search code examples
c#unity-game-enginecollision-detectioncollisioncollider

How can I access the position of a certain tile in a tilemap (unity 2D)?


I am currently trying to find a way to get the position of the specific tile that I collide with. I have a large tilemap with a tilemap collider, and I have a player that has a script (seen below) that should on collision with a tile from that tilemap instantiate a pickup item a random range away from that tile. But because it is the tilemap collider that I am colliding with, the pickups spawn a random distance from 0,0 where the tilemap is positioned. Is there a way I can access the position of the individual tile so that the pickups spawn a random distance from the tile I collide with (or do you have another idea of how to create the same effect)? Thanks so much!

Script:

using UnityEngine;

public class Drops : MonoBehaviour
{
    public GameObject wooddropling;
    public GameObject stonedropling;

    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "trees")
        {
            Instantiate(wooddropling, new Vector3(col.transform.position.x - Random.Range(-3f, 3f), col.transform.position.y - Random.Range(-3f, 3f), 0), Quaternion.Euler(0, 0, Random.Range(0.0f, 360.0f)));
        }
        if (col.gameObject.tag == "stones")
        {
            Instantiate(stonedropling, new Vector3(col.transform.position.x - Random.Range(-3f, 3f), col.transform.position.y - Random.Range(-3f, 3f), 0), Quaternion.Euler(0, 0, Random.Range(0.0f, 360.0f)));`
        }
    }
}

Solution

  • From this forum post and another, you can use collision overlap checks to find tile/positions within the TileMap:

        void OnCollisionEnter2D(Collision2D col)
        {
            ContactPoint2D contact = collision.GetContact(0);
            // Assuming 'tilemap' is your TileMap object.
            Vector3Int cellPosition = tilemap.WorldToCell(contact.point);
    
            // If you need the tile itself.
            TileBase tile = tilemap.GetTile(cellPosition);
            // Or, if you need the tile's position:
            Vector3 tilePosition = tilemap.CellToWorld(cellPosition)
        }
    

    Though given that those referenced posts are old (2015~2018), someone might post a more efficient answer.