2d-extras
2d-extras copied to clipboard
tilemap collisions not working on animated tiles
it may just be me as I am quite new.
In my tilemap, I have some animated, some not and only the unanimated tiles have colliders when a collider is applied. look for the lava which is not animated, it also has a collider (yes all the lava is in the lava tilemap)
Currently, not all the Sprites in the animation of the AnimationTile do not contribute to the collider shape for the TilemapCollider2D. Only the initial Sprite will contribute to the collider shape for the TilemapCollider2D.
I can't really tell from the image, but did you want each animated Sprite in the AnimationTile to update the collider shape when the animation changes the Sprite?
Thanks for the response.
Sorry for the unclear image. In this game, i wanted it to restart if you fell into the lava, however the none of the animated lavas would contribute to the collier.This was fine for this project as I made it if not on the bricks, however for the project I am working on now that will not be possible. Are you planning to fix the collides any time soon? I will do a workaround at the moment however it would be nice to have this at some point.
If you set the collider type of the Animated Tile to Sprite, you should be able to create a collider shape in the TilemapCollider2D for your lava tile.
For example, I have set the collider shape for my animated Waterfall tile here and it has generated collider shapes for these tiles. You can see the collider shape based on the green outlines around it.
Are you unable to generate these shapes for the Lava tile?
I have (what seems to be) a related issue.
EDIT: I also tried this with the animated tiles from this package. I have the same issue using those AnimatedTiles.
Anyway, I'm trying to get a custom animated tile to have a collider - it doesn't need to change with the animation, just needs to be there all the time. In my game, I'm switching between a few different TileMaps fairly frequently (different "planes" of existence), so they're all in memory, and I just activate and deactivate the GameObjects for them when traveling between. The tilemaps are procedurally generated as you explore them.
Strangely, upon exploring tiles for the first time the collision works perfectly. However, after leaving that plane and re-entering (meaning the tilemap, its gameobject, collider, etc. were deactivated and reactivated) the collision for the animated tile type no longer works for the tiles explored previously. (Newly explored tiles of the animated type still have collision.) I've tried using both "Grid" type and "Sprite" type for the ColliderType in the tile - same result.
A brief investigation confirms that the animation has something to do with it - returning false from GetTileAnimationData fixes the collision, but of course it no longer animates. I couldn't find any more information about how the animation or tile data is used, and it didn't look like I could subclass TileMap and change some functionality there - I don't think the methods are exposed. Of course, I'm not too experienced with 2D in Unity and TileMaps so it's likely I'm missing something easy.
Tile code (again, I copied from the docs and added two lines to try to make collision work.)
public class AnimatedTile : TileBase {
public Sprite[] m_AnimatedSprites;
public Tile.ColliderType colliderType;
public float m_AnimationSpeed = 1f;
public float m_AnimationStartTime;
public override void GetTileData(Vector3Int location, ITilemap tileMap, ref TileData tileData) {
tileData.colliderType = colliderType;
if(m_AnimatedSprites != null && m_AnimatedSprites.Length > 0) {
tileData.sprite = m_AnimatedSprites[m_AnimatedSprites.Length - 1];
}
}
public override bool GetTileAnimationData(Vector3Int location, ITilemap tileMap, ref TileAnimationData tileAnimationData) {
if(m_AnimatedSprites != null && m_AnimatedSprites.Length > 0) {
tileAnimationData.animatedSprites = m_AnimatedSprites;
tileAnimationData.animationSpeed = m_AnimationSpeed;
tileAnimationData.animationStartTime = m_AnimationStartTime;
return true;
}
return false;
}
}
Generation code (runs every frame when the plane is enabled)
void UpdateTiles() {
Vector3 playerPos = player.transform.position;
Vector3Int playerTile = player.CurrentTile;
int chunkSize = Mathf.CeilToInt(2*player.LOS)+1;
for(int i = -1; i < chunkSize; i++) {
for(int j = -1; j < chunkSize; j++) {
Vector3Int position = playerTile + new Vector3Int(i - chunkSize/2, j - chunkSize/2, 0);
if(map.GetTile(position) == null && (position - playerPos + new Vector3(.5f, .5f, 0)).magnitude < player.LOS) {
int index = TileIndex(position);
map.SetTile(position, allTerrainData[index].tile);
}
}
}
}
(double edit note: I'm an idiot for not realizing right away from where you were getting the AnimatedTile class....)
However, after leaving that plane and re-entering (meaning the tilemap, its gameobject, collider, etc. were deactivated and reactivated) the collision for the animated tile type no longer works for the tiles explored previously. (Newly explored tiles of the animated type still have collision.) I've tried using both "Grid" type and "Sprite" type for the ColliderType in the tile - same result.
Would you elaborate more about how you are deactivating and reactivating the Tilemap? This would help a lot in identifying the issue.
Also, which version of Unity are you using?
I'm using Unity 2019.3.0f6 (Personal).
I call SetActive(false)
and SetActive(true)
on the parent of the Tilemap object to deactivate and reactivate it.
//planes is a list that contains the parents of the tilemap objects
void ActivateInternal(int destinationLevel) {
for(int i = 0; i < planes.Count; i++) {
if(i == destinationLevel)
continue;
planes[i].gameObject.SetActive(false);
}
planes[destinationLevel].gameObject.SetActive(true);
activePlane = destinationLevel;
}
The actual objects look like below. If it matters, the script with the above ActivateInternal
method is in the "Manager" object (top of the hierarchy). Like I said, the tilemaps are disabled and enabled by SetActive
on the its parent, here the "Terrestrial" and "CavernLayer" objects.
Hi, sorry for the late reply. I checked this out and this is a bug with the Unity Editor and will be fixed in a future version.
I will update here with the version of the Unity Editor that has this fixed!
Thanks for letting me know that it is confirmed a bug!
any updates on this?
@apkatsikas This has been fixed a while back and is available back to Unity 2019.4 I believe.
cool - i will try. my issue was de-parenting and then parenting an animated tile seemed to erase the collider data. hopefully this will fix for me
worked in 2019.4.10f1 - thanks @ChuanXin-Unity