Position Is Offset, How to Align?

Godot Version

v4.2.2.stable.official [15073afe3]

Question

I am trying to spawn actors around a unit. Currently, the actors are spawning, but well offset and outside of the map (see bits circled in red in the image below). This offset is also happening to the collision shapes I am instantiating to test if the desired spawn position is free, as well as the grid I am drawing, so I am clearly doing something wrong with the positions.

I’ve tried global_position and position, both referring to and/or setting each.

Am I missing something obvious? Any help would be greatly appreciated!

## spawn required number of actors randomly around the unit's position
func _spawn_actors() -> void:
	var max_attempts: int = 32
	var pos_variance: int = floor(spawn_radius / 2)

	for i in unit_size:
		for j in max_attempts:

			var rand_x : int = randi_range(global_position.x - pos_variance, global_position.x + pos_variance)
			var rand_y : int = randi_range(global_position.y - pos_variance, global_position.y + pos_variance)
			var spawn_pos: Vector2 = Vector2(rand_x, rand_y)

			var space_state: PhysicsDirectSpaceState2D = get_world_2d().direct_space_state
			var shape_query_params: PhysicsShapeQueryParameters2D = PhysicsShapeQueryParameters2D.new()
			var shape: CircleShape2D = CircleShape2D.new()
			shape.radius = 6
			shape_query_params.shape = shape
			shape_query_params.transform.origin = spawn_pos

			# check query
			var results: Array[Dictionary] = space_state.intersect_shape(shape_query_params)
			var filtered_array: Array = results.filter(
				func (collision_object):
						return collision_object.collider.is_in_group("actor")
			)

			# visual and console output for debugging
			#print(results)
			var area_2d = Area2D.new()
			area_2d.position = shape_query_params.transform.origin
			var collision_shape_2d = CollisionShape2D.new()
			var collision_shape = CircleShape2D.new()
			collision_shape.radius = shape.radius
			collision_shape_2d.shape = collision_shape

			area_2d.add_child(collision_shape_2d)
			add_child(area_2d)

			# if no collisions
			if filtered_array.size() == 0:
				var actor: Actor = actor_scene.instantiate()
				actor.position = spawn_pos
				print("Unit pos: ", global_position, " | actor (", actor, ") spawned at: ", spawn_pos)
				add_child(actor)
				break

The problem is probably the mixed use of global and local coordinates. spawn_pos is in global coordinates, but you’re assigning it to the position of a child node.

I suggest you change the line to this

actor.global_position = spawn_pos

and then swap it with the line

add_child(actor)

because actor needs to be added as a child before setting global_position.

1 Like

That was it! Thank you very much! (the debug visuals are still spawning elsewhere, but you’ve given me something to work with. :slightly_smiling_face: )