2
votes

(I've asked this question over at Unity Answers too, but it can sometimes take a while to get a response there, if I get an answer there I'll put it here too.)

I'm making a tile based game that uses Grid > Tilemap with cell layout as Hexagon.

The player can move a certain distance based on movement level. My plan is to highlight valid movement spaces in green and invalid in red. To do this I've got a child GameObject called MovementRange that has a CircleCollider2D attached with it's radius matching the player's movement level. All settings as default.

The TileMap uses a TileMapCollider2D. As each tile on the grid is smaller than the actual grid hexagon this means that each tile is separated by a gap. The TileMapCollider2D correctly assigns each tile a hexagonal collider. All settings as default. The tilemap also has a Rigidbody2D set as Kinematic and Use Full Kinematic Contacts checked.

This is the function used to highlight the tiles in range:

void HighlightCellsInRange(Collision2D collision)
 {
     Vector3 hitPosition = Vector3.zero;
     ContactPoint2D[] contacts = new ContactPoint2D[100];
     int contactCount = collision.GetContacts(contacts);

     for (int i = 0; i < contactCount; i++)
     {
         Vector3Int tile = _tileMap.WorldToCell(contacts[i].point);
         _tileMap.SetTile(tile, _greenTile);
         _tilesInRange.Add(tile);
     }
 }

This works correctly for any tile that a collision is registered for. The problem is that some tiles don't register collisions (and others have multiple collisions).

Here are some screen shots where you can see what's happening:

I have generated gizmo spheres at all of the collision contacts returned. The circle collider is selected so you can see that clearly there are missing tile collision contact points. There's 6 missing in the very center of the circle collider!

CircleCollider2D missing contacts

In this screen shot you can see the grid and that every tile is displaying active hexagonal colliders.

TilemapCollider2D tiles colliders

I've tried changing the settings on the circle collider and the tilemap collider but I can't understand why some of the collisions are not registering.

Any advice would be appreciated. Thanks

1
Up until very recently there have been some bugs with 2D colliders not reporting some collisions. It might be as recent as 2018.3.x late betas (last few weeks) that finally almost completely fixed this. If you can, update to the latest 18.3.x beta, and see if you get the same problem. Please... PLEASE backup your project before opening it in 2018.3 betas... as you won't be able to reopen it in 18.2 versions afterwards. I got caught once, with this. It's a nightmare.Confused
Hi @Confused, thanks for your response. That's interesting, I've downloaded 18.3b to see if there is a difference in the calculations. If not I'll file a bug report. I have a work around I'm using at the moment which rotates and checks the tiles a set distance at every 12 degrees. It works but it's not pretty.Kyohei Kaneko
Afraid the problem still exists. It appears the individual tile colliders in a tilemapcolldier2d are not currently implemented to allow correct collision points. They currently allow physical collision, to prevent colliders passing through them, but it appears not this use case. I'll file a bug report. Thanks for your time.Kyohei Kaneko
You could try using a collider as a trigger, and then checking for stay... that might work more reliably... The oddness of collision reports not reporting plagued me for most of this year, I wasn't aware of the bug and couldn't imagine it was bugged, so tried a million other things thinking it was my fault. It wasn't. Which is unusual ;) I've dome to learn that Unity has a lot of little annoying bugs that you wouldn't expect to be in something that claims to be so incredibly popular.Confused
@Confused, I had already tried Trigger Colldiers I'm afraid, the problem is that they only return a Collider2D object not a Collision2D object, the collider2d doesn't have any info on contact points. The tilemapcolldier2d is only a single collider so I just get a hit on the entirety of the Tilemap ... which isn't very useful!Kyohei Kaneko

1 Answers

2
votes

I ended up sending a bug report to Unity, which they accepted (eventually).

They first tried to explain it as "It doesn't fire if the collider is already over the object". Which it wasn't anyway, and doesn't explain why the other tiles were still collided with. So I screen recorded a collider growing from 0.1 radius to full size and tracking the contact points with gizmos the entire time. You could clearly see the contact points starting out fine, then suddenly disappearing, especially on the right hand side of the tilemap as it grew.

So as it stands, collision against individual tiles is not reliable with TilemapCollider2D when the collider contacts more than a few tiles simultaneously.

Here's a GIF of the bug for those interested: enter image description here