I wonder whether how I structured my project might actually be the problem. The way I do my Levels are as such:
and the level I wish to transition to:
Each of the doors in the levels have an body_shape_entered and exited signal so that I can know when to transition the player. (there is also an animation to open/close the door)
public void OnSpaceDoorTopExitBodyShapeEntered(RID objectEnteredRid, KinematicBody2D objectEntered, int bodyShapeIndex, int localShapeIndex)
{
if (objectEntered.Name == "Party")
{
//Entered the animation area. Animate door to open
_spaceDoorSprite.Animation = "open";
if (localShapeIndex == 1)
{
// //Transition
var sceneManager = GetNode<SceneManager>("/root/GameWorld/SceneManager");
sceneManager.SwitchScene(TransitionScene, DoorName);
}
}
}
Now in my SceneManager, there is a SwitchScene method, that does a little bit of a fade animation, with a signal to itself via an AnimationPlayer that will perform the actual switch when the animation complates:
public void SwitchScene(string scenePath, string doorName)
{
TransitionDoorName = doorName;
TransitionPath = scenePath;
var animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
animationPlayer.Play("fade_to_black");
GD.Print("Fading to black");
}
private void OnAnimationPlayerAnimationFinished(string animationName)
{
if (string.Equals(animationName, "fade_to_black"))
{
GD.Print("Faded to black");
//EmitSignal(nameof(Transitioned), "fade_to_black");
var animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
animationPlayer.Play("fade_to_normal");
//EmitSignal(nameof(Transitioned));
//GD.Print("Signal transmitted");
GotoScene(TransitionPath);
}
if (string.Equals(animationName, "fade_to_normal"))
{
GD.Print("Finished fading");
}
}
I've already posted the 'GotoScene' method above.
So these doors call into the SceneManager node, that sits under the GameWorld Node /root/GameWorld/SceneManager and when switched out, should change,for example, /root/GameWorld/BFZuluQuarters with /root/GameWorld/BFZuluWestHallway.
Each of the Levels have code in the _Ready function to determine where to spawn the player:
public override void _Ready()
{
var sceneManager = GetNode<SceneManager>("/root/GameWorld/SceneManager");
if (!string.IsNullOrWhiteSpace(sceneManager.TransitionDoorName))
{
var playerNode = GetNode<Party>("Party");
if (string.Equals(sceneManager.TransitionDoorName, "QuartersDoor"))
{
playerNode.Position = new Vector2(480,416);
}
}
}
Could it be that these doors, which sit inside each levels, that call out to the Singleton/Autoloaded SceneManager, to replace its own parent level, that causes this effect? I would imagine if a child node calls out to a grandparent/higher up node to replace its own parent is not an issue.