Position Chosen being weird and not being where i want it to be D:

For my enemy spawning I have a plane mesh and a script to chose a position somewhere on it. I use that function to spawn enemies and set them to that position. The issue is they are spawning at normal X and Z positions but not Y. Here’s the relevant code:

extends MeshInstance3D

class_name SpawnLocation


var TOP_RIGHT_POS : Vector3
var TOP_LEFT_POS : Vector3
var BOTTOM_LEFT_POS : Vector3
var BOTTOM_RIGHT_POS : Vector3

func _ready() -> void:
	visible = false
	TOP_RIGHT_POS = get_corner_pos(Vector2i(1, 1))
	TOP_LEFT_POS = get_corner_pos(Vector2i(-1, 1))
	BOTTOM_LEFT_POS =get_corner_pos(Vector2i(-1, -1))
	BOTTOM_RIGHT_POS = get_corner_pos(Vector2i(1, -1))

func get_corner_pos(smth : Vector2i) -> Vector3:
	var plane : PlaneMesh = mesh
	return Vector3((global_position.x) + (((plane.size.x/2) * scale.x) * smth.x), global_position.y, (((plane.size.y/2) * scale.z) * smth.y))
## Returns a spawn location in the order: top right, top left, bottom left, bottom right.
func get_spawn_location() -> Array[Vector3]:
	return [
		TOP_RIGHT_POS,
		TOP_LEFT_POS,
		BOTTOM_LEFT_POS,
		BOTTOM_RIGHT_POS,
		]

## Returns a random spawn location somewhere on the plane
func random_spawn_location() -> Vector3:
	var x_pos : float = randf_range(TOP_RIGHT_POS.x, TOP_LEFT_POS.x)
	var z_pos : float = randf_range(TOP_RIGHT_POS.z, BOTTOM_RIGHT_POS.z)
	print("spawn location thing" + str(Vector3(x_pos, global_position.y, z_pos)))
	return Vector3(x_pos, global_position.y, z_pos)

extends Node

class_name spawner

var flyingenemy := preload("res://scenes/enemies/enemy.tscn")
var explosiveguy := preload("res://scenes/enemies/explosive_guy.tscn")
var golem := preload("res://scenes/enemies/golem.tscn")
var bomber := preload("res://scenes/enemies/bomber.tscn")
var basicenemy := preload("res://scenes/enemies/basic_enemy.tscn")
var turret := preload("res://scenes/enemies/turret.tscn")

@export var spawning_locations: Array[SpawnLocation]

@export var Enemies : Array[PackedScene] = [
flyingenemy,
explosiveguy,
golem,
bomber,
basicenemy,
turret,
]

func createenemies() -> void:
	if Enemies.size() > 0:
		for i in range(randi_range(2, 4)):
			var enemyIndex = randi_range(0, Enemies.size() - 1)
			while  enemyIndex == 0 && has_node("enemy"):
				enemyIndex = randi_range(0, Enemies.size() - 1)
			spawnEnemy(enemyIndex)
			if Enemies[enemyIndex] == turret:
				i -= 1

func spawnEnemy(enemyIndex: int):
	var location_thing = spawning_locations[randi_range(0, spawning_locations.size() - 1)]
	
	if Enemies[enemyIndex] == flyingenemy:
		var enemySpawn : Node3D = Enemies[enemyIndex].instantiate()
		add_child(enemySpawn)
		enemySpawn.global_position = location_thing.random_spawn_location()

	elif Enemies[enemyIndex] == explosiveguy:
		var enemySpawn : Node3D = Enemies[enemyIndex].instantiate()
		add_child(enemySpawn)
		enemySpawn.global_position = location_thing.random_spawn_location()

	elif Enemies[enemyIndex] == golem:
		var position_chosen : Vector3 = location_thing.random_spawn_location()
		for i in range(randi_range(1, 3)):
			var enemySpawn : Node3D = Enemies[enemyIndex].instantiate()
			add_child(enemySpawn)
			enemySpawn.global_position = position_chosen + Vector3(randf_range(-7, 7), 0, randf_range(-7, 7))

	elif Enemies[enemyIndex] == bomber:
		var enemySpawn : Node3D = Enemies[enemyIndex].instantiate()
		add_child(enemySpawn)
		enemySpawn.global_position = location_thing.random_spawn_location()

	elif Enemies[enemyIndex] == basicenemy:
		var position_chosen : Vector3 = location_thing.random_spawn_location()
		for i in range(randi_range(3, 6)):
			var enemySpawn : Node3D = Enemies[enemyIndex].instantiate()
			add_child(enemySpawn)
			enemySpawn.global_position = position_chosen + Vector3(randf_range(-7, 7), 0, randf_range(-7, 7))

	elif Enemies[enemyIndex] == turret:
		var enemySpawn : Node3D = Enemies[enemyIndex].instantiate()
		add_child(enemySpawn)
		enemySpawn.global_position = location_thing.random_spawn_location()

Basic enemy is what I’m testing with. When printing the position of the enemy’s global position after spawning it, it seems to be normal. This is the only relevant thing that happenes in the enemie’s ready function:

	process_mode = Node.PROCESS_MODE_DISABLED
	hide()
	await get_tree().process_frame
	if gamemanager.dungeon_main != null:
		gamemanager.dungeon_main.connect('entered_room', actually_spawn)

Sorry if this is to much info, if nobody can find anything I’ll try to narrow it down more. I just want to see if somebody knows a glaring issue with something

func _ready() -> void:
    print("hello world")

Looks like the y position is determined by the global_position of your MeshInstance3D object. If you move it up, the spawned things should move up correspondingly.

Yes, moving up the spawner does make the enemies move up. I think some math somewhere is wrong because moving the room away from the world origin causes the issue.

1 Like