• 2D
  • add TileMap collision via code.

is here any proper way to add collision to TileMap at runtime or while tool-mode? i've tried to use following code to add collision to cells:

var shape = ConvexPolygonShape2D.new()
var shape_points: PoolVector2Array = [Vector2(0, 0), Vector2(16, 0), Vector2(16, 16), Vector2(0, 16)]
shape.set_points(shape_points)
tile_add_shape(id, shape, Transform2D(0, Vector2D())

but it overrides tilemap.tscn file like crazy. 320 lines becomes 8000.

i guess, i figured out. Here i've got:

func add_collision(cell):
	var body = StaticBody2D.new()
	add_child(body)
	
	var shape = RectangleShape2D.new()
	shape.set_extents(Vector2(8, 8))

	for cell in get_used_cells():
		var collision = CollisionShape2D.new()
		collision.set_shape(shape)
		collision.set_position(map_to_world(cell) + shape.extents)

		body.add_child(collision)
		body.collision_mask = collision_mask
		body.collision_layer = collision_layer

logic it's simple, create StaticBody2D with bunch of collision shapes. But that method is slower that tilemap collision

did anyone know why code somethimes not work properly? in some tilemas it will create normally, sometimes with huge offset, someties runtime goes to infinite loop.

func _ready():
	for cell in get_used_cells():
		var shape = ConvexPolygonShape2D.new()
		shape.set_points([Vector2(0, 0), Vector2(16, 0), Vector2(16, 16), Vector2(0, 16)])  # rectangle
		tile_set.tile_add_shape(0, shape, Transform2D(0, map_to_world(cell) - cell_size))
		tile_set.tile_set_shape(0, 0, shape)

Maybe the get_used_cells function is being updated by the tile_add_shape and/or tile_set_shape functions? That could explain the infinite loop. I'd try something like this and see if that fixes the infinite loop issue:

func _ready():
	# Call get_used_cells outside of the for loop condition
	var used_cells = get_used_cells()
	for cell in used_cells:
		var shape = ConvexPolygonShape2D.new()
		shape.set_points([Vector2(0, 0), Vector2(16, 0), Vector2(16, 16), Vector2(0, 16)])  # rectangle
		tile_set.tile_add_shape(0, shape, Transform2D(0, map_to_world(cell) - cell_size))
		tile_set.tile_set_shape(0, 0, shape)