Reparenting Object Pooled Decals Causing Weird Scale

Godot Version

4.4.1

Question

Hello, I have an object pool of decals that I am am hoping to reparent to other objects so they can move with dynamic objects like rigid body crates and stuff. I’ve noticed when reparenting the decal for the first time, it works fine, but when the same decal is “spawned” the second time, it seems to keep the last parents scale.

var object_succesfully_spawned: bool = false
	for i in range(allocated_objects):
		if object_index >= allocated_objects:
			object_index = 0
		if "available" in object_array[object_index] and object_array[object_index].available:
			object_array[object_index].global_position = spawn_location
			if spawn_rotation: rotate_object(object_array[object_index], spawn_rotation)
			if object_array[object_index].has_signal("object_hidden"):
				object_array[object_index].object_hidden.connect(func(): unparent(object_array[object_index]),CONNECT_ONE_SHOT)
			if object_array[object_index].has_method("spawn_object"):
				object_array[object_index].spawn_object()
				if parent : object_array[object_index].reparent(parent)
				print(object_array[object_index].scale)
				object_succesfully_spawned = true
				return object_array[object_index]
			else:
				push_error("Object doesn't have spawn method.")
				return null
			
			object_index += 1
			break
		object_index += 1
	if !object_succesfully_spawned:
		printerr("object not available, try allocating more objects to this spawner.", self)
		pass
	return null

I’ve also tried writing a function that changes all the nodes properties back to it’s default values by a signal that is emitted by the object when it is done hiding, but I’m still getting the same results.

func unparent(object : Node3D)->void:
	print("unparented")
	object.reparent(Engine.get_main_loop().current_scene)
	object.position = Vector3.ZERO
	object.rotation = Vector3.ZERO
	object.global_position = Vector3.ZERO
	object.global_rotation = Vector3.ZERO
	object.scale = Vector3.ONE
	object.global_scale(Vector3.ONE)

here’s the link to what it looks like:

reparent() keeps global transforms by default. You can disable this by passing false as the second argument.

Do you need object pooling at all? Usually unless you’re working on a bullet hell game, you shouldn’t need to pool objects.
Especially if your solution works well without object pooling, I’d just opt to not use object pooling.

Cant you just clear the pool and refill it after reparenting?
Sure, waste lf CPU but will anyone ever notice?
In which situations would you reparent?

Edit

Or save initial scale etc in a buffert that you check when reparenting?

The problem was in the object_hidden signal. It was referencing the wrong object in the for loop, so It was reparenting the the most recent object that was pulled from the pool rather than one for each iteration of the pool.

I fixed it by connecting a signal when each object is originally created. So the signal will be emitted when each object is hidden.

func create_objects()->void:
	object_array.resize(allocated_objects)
	for i in range(allocated_objects):
		var instance := object_scene.instantiate()
		object_array[i] = instance
		
		Engine.get_main_loop().current_scene.add_child.call_deferred(instance)
		if object_array[i].has_signal("object_hidden"):
				object_array[i].object_hidden.connect(unparent.bind(object_array[i]))
		if instance.has_method("hide_object"):
			instance.hide_object()
		else:
			push_error("object doesn't have hide method.")