Duplicating AnimatableBody2D issues

Godot Version

Godot 4.3 stable mono official (77dcf97d8)

Question

Hello all,

I am very new to game dev and Godot, and I am learning with a 2D platformer.

I am trying to have platforms move horizontaly thoughtout a level, and I want to have the possibility to keep spawing the same platform at regular intervals.

I have created a AnimatableBody2D, with an animation player to set the platform movement.

I have made an Area2D with a collision shape that will act as the trigger to start the platform moving, and with the option to keep spawning the same platform at a set delay.

here is the script for my trigger:

using Godot;

public partial class TriggerPlatformAnim : Area2D
{
	[Export] private AnimatableBody2D platform;
	[Export] private bool keepSendingPlatforms = false;
	[Export] private float delay = 5.0f;
	private Godot.Timer timer;

	public override void _Ready()
	{
		Connect("body_entered", new Callable(this, "OnBodyEntered"));

		timer = new Timer();
		timer.WaitTime = delay;
		timer.Connect("timeout", new Callable(this, "OnTimerTimeOut"));
		AddChild(timer);
	}

	public void OnBodyEntered(CharacterBody2D player)
	{
		StartAnim(platform);
		if (keepSendingPlatforms)
		{
			timer.Start();
		}
		Disconnect("body_entered", new Callable(this, "OnBodyEntered"));
	}

	private void OnTimerTimeOut()
	{
		GD.Print("sending a new platform!");
		AnimatableBody2D np = (AnimatableBody2D)platform.Duplicate();
		AddChild(np);
		StartAnim(np);	
	}

	private void StartAnim(AnimatableBody2D animatableBody2D)
	{
		var animator = animatableBody2D.GetNode<AnimationPlayer>("AnimationPlayer");
		if (animator != null)
		{
			animator.Play("move");
			GD.Print("starting platform");
		}
	}
}

So, this module takes a platform as an AnimatableBody2D as a required parameter. This object should have a child which is an AnimationPlayer, with an animation called “move” (as I plan to reuse this script for all kind of platforms).
Optional parameters are keepSendingPlatforms, and delay, in case I want to have a repeatable platform.

When I enter the collision area of the trigger, it checks if there is an animation called move, and it starts it. And if keepSendingPlatforms is true, a timer will be started.

At the timer timeout, the original platform is duplicated, and animated.

However, when var np = platform.Duplicate(); is executed, and the player is standing on the original platform, the player is sent back to the position it interacted first with the original platform. I don’t know if this is very clear, so here is an example, where you will see what I am talking about: https://www.youtube.com/watch?v=0QSdlt1L5l8 (this is a simplified level to highlight the issue - I am not THAT bad at level design! and sorry for the potato quality)

So I guess there is something I don’t understand about Duplicate(). Would any one have an idea about why this is happening, and what I could do differently to fix the issue?

Thanks

I have replaced the Duplaicet() statement with a PackedScene, but still don’t understand what is happening…

	private void OnTimerTimeOut()
	{
		GD.Print("sending a new platform!");
		AnimatableBody2D np = GD.Load<PackedScene>(platform.SceneFilePath).Instantiate<AnimatableBody2D>();
		GetTree().Root.AddChild(np);
		np.AddChild(platform.GetNode("AnimationPlayer").Duplicate());
		StartAnim(np);
	}