- Home /
How to detect on which exact tile a collision happened?
I have a tilemap with a TIlemapCollider2D with it's trigger on true, and a script that detects the collision with the tilemap through OnTriggerEnter2D. It detects collision, but I wan't to know the exact position of the Tile that detected the collision. Is there any way to do that?
Answer by Tomer-Barkan · Nov 16, 2018 at 06:00 PM
For starters, you need the collision point. OnTriggerEnter2D is very problematic on this aspect, since it doesn't provide collision data, only the collider. So you don't have the contact points. You can either calculate them manually based on the position of the hitting object, or manually do a physics raycast on the collider to get the collision info. This is a bit of an oversight on Unity's side. Another option is to use a non-trigger collider and make the rigidbody kinematic, so it will not be affected by forces. See here. If you use OnCollisionEnter2D then you can use collision.GetContacts() to find the contact points.
Now, once you have the contact points, you can use the following:
use GetComponent() on the collider to get the tilemap itself.
use Tilemap.layoutGrid to get the grid from the TileMap.
use Grid.WorldToCell with the collision point to get the cell coordinates in which the collision point is.
use TileMap.GetTile or TileMap.GetInstantiatedObject to get the TileBase or GameObject in the collision tile.
Even if i change the function to OnCollisionEnter2D it can only give me the points of collision, but not the exact position of the tile that i collided with.
I gave you a long list of commands on how to get the tile from the collision points... Did they not work? What was the problem?
I didn't try the raycast method, but I highly supect it would give me the same results as if I use collision.GetContacts(). The problem was that the position where the object collided with the tilemap isn't the same as the exact position of the tile, even if I use WorldToCell().
Answer by Shlomito · Jun 02 at 03:00 AM
@Tomer-Barkan wouldn't the tiles be solid if IsTrigger is off, even if it has a kinematic rigidbody? When I try it it is, and the whole point of IsTrigger being on in the first place is so that other objects can go through it.
It may be related to newer Unity versions replacing the isKinematic box with the Dynamic/Kinematic/Static options, but idk how to do it otherwise. I was using OnTriggerEnter and using the ClosestPoint function with the player's position but it didn't seem to be reliable.
Edit: I found that as long as the collider of the tile is not touching the edges, and the player is less than a tile big, this approach does work, but it's certainly not perfect.