Hello Guest

Author Topic: Tilemap: collision tile id problem  (Read 8008 times)

ccampama

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 35
    • View Profile
Tilemap: collision tile id problem
« on: October 07, 2013, 01:15:35 pm »
Hi again,

we have faced another problem using tilemaps: almost all of our tiles in a tilemap have a string with a kind of "type" label on it, in the Data section. But when we let a gravity-driven sprite collide with the tilemap, we find that on some of the tiles (always the same ones), the collision works fine but "GetTileIdAtPosition" returns "-1" (as if no tile was there?), so we can't get the TileInfo for this collision. Where could we start to look on the problem? Any hint on what could we be doing wrong?
 Some of the tiles in the tilemap have prefabs associated with them, and these ones always work ok. The problem happens with some of the tiles that have a string set but not any prefab (the funny thing is that SOME of the tiles with no prefabs but with string seem to work fine!).
 Please note we are sharing the project via SVN (could it be any indexing conflict or something like that?). Should we do any reindexing or something? (we tried the one in the "2D Toolkit" menu in Unity menu bar, but with no success)

 The collision code is like:
Code: [Select]
int tileId = tileMap.GetTileIdAtPosition(collision.transform.position, 0);
if (tileId >= 0)
{
      tk2dRuntime.TileMap.TileInfo tileInfo = tileMap.GetTileInfoForTileId(tileId)
      string str = tileInfo.stringVal;
}

 Thank you in advance for any help or hint you might provide.

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Tilemap: collision tile id problem
« Reply #1 on: October 07, 2013, 11:45:56 pm »
GetTileIdAtPosition only returns -1 if
1. There is no tile there (i.e. the collision point is actually in the empty space above the tiles or is on the tiles such a way that floating point precision confuses the system intermittently. Offsetting the collision point down slightly will help here.
2. The tile is outside the tilemap bounds. Unlikely if you've collided sensibly.

When a tile has a prefab its no longer a tile but spawned as a prefab. You can do whatever you like that way - eg. give the tile its own collider, etc.

ccampama

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tilemap: collision tile id problem
« Reply #2 on: October 09, 2013, 11:05:43 am »
First of all, thank you for your prompt response.

The 2nd point, as you say, is unlikely to happen because the collisions work really fine.

So I've tried changing the code of the collision trigger to add a small vector to the collision point; this vector is ensuring that the collision is not on the bounds, but closer to the center of the collided tile. But the results are just the same as if we didn't offset this collision point (and I've verified the code printing out the vector): the result is "-1".

Then I've printed out all the collision coords to see them ("collision.transform.position") and to my surprise, in some tiles (the could seem random but they are always the same ones) "OnCollisionEnter" is not being called! And in all the other ones where "OnCollisionEnter" is being triggered, "collision.transform.position" is always (0, 0, 0)!! Then if I print "collision.contacts[0].point" it is fine and GetTileIdAtPosition works great, but as with many tiles "OnCollisionEnter" is not being called, I cannot play a collision SFX :(

I've unlinked, regenerated and checked the "TileMap Render Data" during runtime and the colliders are fine along with their physics materials. Everything seems ok, but...  :-\
The gameobject that is colliding with the TileMap is a ball with a sphere collider, with its physics material, a rigidbody of mass 1, not kinematic, with gravity... And all the collisions work visually perfectly. The problem is that "OnCollisionEnter" is not being called with many tiles, and with the tiles that it is being called, "collision.transform.position" is zero ??

What could I have missed? What could be wrong? I don't know where more to look at. Do you need any more data that I could check and tell you back about?

Thank you VERY MUCH for your help!

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Tilemap: collision tile id problem
« Reply #3 on: October 10, 2013, 09:17:44 am »
The whole tilemap is treated as one collider (divided by partitions). So, you might not get OnCollisionEnter on each tile, you might get OnCollisionStay when youve moved but still are colliding.

ccampama

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tilemap: collision tile id problem
« Reply #4 on: October 10, 2013, 05:07:25 pm »
Ok. Exactly! That's what I was guessing: that the ball collides with what I think you call "Chunk"'s (the TileMap partitions), not with the individual tiles (except for the prefabs, as you said before). So when the contact is constant and whithin the same chunk, there is no more entering, but staying. What I have done is to put the special tiles that I wanted to play a SFX when collided as prefabs (they are not too many, and this way I don't have to mess with CollisionStay). And the other problem that I faced what that "collision.transform.position" was Zero. That is important to have in mind, as you don't collide with tiles when they are not prefabs, so the position you receive is from the TileMap GameObject (or the colliding chunk, I haven't checked this), that in my case stood at Zero! So my collision code in the ball script is now something like:
Code: [Select]
int tileId = TileMap.GetTileIdAtPosition(collision.transform.position, 0);
if (tileId < 0)
{
    tileId = TileMap.GetTileIdAtPosition(collision.contacts[0].point, 0);
}
This way I can get the tileId no matter if it is a prefab or a "regular" one. Now everything seems to work fine.
Hope this helps if someone finds the same problem. With the collision contact point you can get which tile has been collided in case you collide with "regular" tiles. Great.

Thank you again for your assistance!

ccampama

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 35
    • View Profile
Re: Tilemap: collision tile id problem
« Reply #5 on: December 02, 2013, 08:33:17 pm »
...and this is the collision script that I had to write when switching to 2D physics (with the offset stated by unikron):
Code: [Select]
int tileId = TileMap.GetTileIdAtPosition(collision.transform.position, 0);
if (tileId < 0)
{
Vector2 collisionPoint;
collisionPoint = collision.contacts[0].point;
collisionPoint -= ((Vector2)this.transform.position - collision.contacts[0].point).normalized * 0.5f;
tileId = TileMap.GetTileIdAtPosition(collisionPoint, 0);
}
It works like a charm for me. Hope this helps  ;)