-
-
Notifications
You must be signed in to change notification settings - Fork 18.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Area2D reports TileMap in the signals, when collide with the tiles #24739
Comments
TileMaps don't instance nodes for every single tile. Tiles are not individual nodes, that's why your area does not report |
But the signal handler method of body_entered and others signals Area2D expects PhysicsBody2D. But he gets TileMap. They are only linked by Node2D, which makes type casting strange. I implemented a projectile based on Area2D. The projectile must ignore all bodies with OneWayCollision. I want to get a CollisionShape2D or CollisionRegion2D with which body the collision occurred. Or somehow else get OneWayCollision. I would not like to make platforms as separate scenes. |
I think this is a documentation issue here as the |
I'm having a similar issue with this in 3.1 alpha 5, where I'm trying to use the Here's what I get from the signal: The interesting part here is the func _save_collision_data(body_id:int, body:TileMap, body_shape:int, area_shape:int) -> void:
var tset: TileSet= body.tile_set
var cellv: Vector2 = body.get_used_cells()[body_shape]
var tile_id: int = body.get_cellv(cellv)
var auto_coord: Vector2 = body.get_cell_autotile_coord(cellv.x, cellv.y)
for shape_data in tset.tile_get_shapes(tile_id):
if shape_data['autotile_coord'] == auto_coord:
print(shape_data) # {autotile_coord:(3, 0), one_way:False, shape:[ConvexPolygonShape2D:1174], shape_transform:((1, 0), (0, 1), (0, 0))} Note, the transform, and the points of the shape, are both kinda useless on their own. You can use This is a bit cumbersome. But, in case you want to get a Shape2D from collision data and those aren't problems for you, the above workaround could be helpful if baked into a script attached to the TileMap: # filename: my_tile_map.gd
extends TileMap
func get_shape_data(tile_idx:int) -> Dictionary:
var cellv := get_used_cells()[tile_idx]
var tile_id := get_cellv(cellv)
var auto_coord := get_cell_autotile_coord(cellv.x, cellv.y)
for shape_data in tile_set.tile_get_shapes(tile_id):
if shape_data['autotile_coord'] == auto_coord:
return shape_data EDIT obviously, change as needed if you're not using autotiles Nice-to-haves would be to not have to iterate over all the shapes in the TileSet. I couldn't find a good way to get the exact index of the given tile in that shapes array. Of course, this doesn't solve the root issue: the signal signature states it will give a PhysicsBody2D, which in the case of a TileMap it clearly doesn't. EDIT I've continued testing this and I think there's either something broken in TileMap, or my understanding of the interface. Given a pos vector from Looking at the source, I don't think the Array is returned in any particular order, not least of all in regards to the I take back my earlier suggestion until I can be certain the |
TileMap instances internally an StaticBody2d or KinematicBody2D depending on the property setup. This like this since Godot1.0 |
@MarianoGnu to clarify, do you mean actual StaticBody2D and KinematicBody2D nodes, or PhysicsServer objects? From what I see in the code, I think Tilemap only deals with server RIDs (I didn't know tilemaps could have kinematic bodies Oo) |
TileMap instances bodies inside the PhysicsServer, there's not a node for this (in fact i belive it instances a body per space, the space is divided on quadrants to reduce the collision tests at minimum) |
I think I found out why the coordinates are wrong. |
Those signals receive either a PhysicsBody2D or a TileMap object, and what the emitting method checks internally is only that the object is a Node. In theory any Node could go through these signals if they talk directly to the PhysicsServer2D. Also updated docs. Fixes godotengine#27076. Might need further (compat breaking) improvement as this API is a bit confusing, cf. godotengine#24739.
See #30043 (comment). This can likely be fixed properly for 4.0, so assigning to that milestone. |
Those signals receive either a PhysicsBody2D or a TileMap object, and what the emitting method checks internally is only that the object is a Node. In theory any Node could go through these signals if they talk directly to the PhysicsServer2D. Also updated docs. Fixes godotengine#27076. Might need further (compat breaking) improvement as this API is a bit confusing, cf. godotengine#24739.
Anyone struggling with this, I found a work around to do what I needed here: godotengine/godot-proposals#2543 Don't forget to copy your collision bits to the parent when you make it! |
Godot version:
Godot 3.1-a4
OS/device including version:
Linux Mint 19.1
CPU: Intel Pentium G3250 (2) @ 3.200GHz
GPU: NVIDIA GeForce GTX 750
Issue description:
Area2D, when overlapping with the TileMap, sent a signals (body_centered, body_exited, body_shape_entered, body_shape_exited). But as the 'body' argument sends a TileMap. Maybe instead it should sent StaticBody2D / KinematicBody2D depending on the settings of the TileMap?
Steps to reproduce:
Collide Area2D and Tile with CollisionShape. Area2D signals will contain TileMap.
Minimal reproduction project:
CollideArea2DAndTileMap.zip
The text was updated successfully, but these errors were encountered: