0

Hey there I have a function which positions a KinematicBody2D's (the Player) body next to a Node2D (a portal). 2 portals are linked together and when the player enters portal X in Scene A they are placed next to the corresponding portal X in Scene B and vice versa. Here is the function:

func fix_player_position(entry_portal_link_id):
    var pos = exit_positions[entry_portal_link_id]
    var new_pos: Vector2
    print("Current entry points for ")
    print(exit_positions)
    $player.set_global_position(Vector2(0,0))
    print("Player's position before change: " + str($player.get_global_position()))

    if portal_list[entry_portal_link_id].landing_point == Direction.Up:
        new_pos = Vector2(pos.x, pos.y-64)
    elif portal_list[entry_portal_link_id].landing_point == Direction.Down:
        new_pos = Vector2(pos.x, pos.y+64)
    elif portal_list[entry_portal_link_id].landing_point == Direction.Left:
        new_pos = Vector2(pos.x-64, pos.y)
    elif portal_list[entry_portal_link_id].landing_point == Direction.Right:
        new_pos = Vector2(pos.x+64, pos.y)
    $player.set_global_position(new_pos)
    print(pos)
    print(new_pos)
    print($player.get_global_position())

here we get the position of the Node2D, reset the players (KinematicBody2D) position to (0,0) apply an offset depending on which side we want to place the KinematicBody2D, and then set the new position and print out all the positions. However it doesn't work correctly. Here is the last output

Current entry points for 
{house_link1:(-3807.48999, 11041.799805), house_link2:(-4132.839844, 10655)} # We store the positions in a dictionary using the portal ID
Player's position before change: (-26252.199219, 11936) # This is supposed to be (0,0)
(-4132.839844, 10655) # The pos variable, i.e the stored position of the Node2D
(-4132.839844, 10719) # The new_pos, i.e. the intended position of the character
(-30385.039062, 22655) # The position of the character after setting

The # comments are added in by me to clarify what is being printed out. As you can clearly see the set_global_position call is not setting the position correctly. However it does set the players position correctly on a different scene.

Scene A -> Scene B, works correctly

Scene B -> Scene A, suddenly does not work correctly.

As you can see I'm a bit lost here, is this a bug within gdscript itself? Or am I an idiot and doing something wrong?

Here is the full output of going from Scene A -> Scene B -> Scene A

Current entry points for 
{house_link1:(32, -288), house_link2:(-355.494995, -477.505005)}
Player's position before change: (0, 0)
(-355.494995, -477.505005) # pos
(-355.494995, -413.505005) # new_pos
(-355.494995, -413.505005) # players position

Current entry points for 
{house_link1:(-3807.48999, 11041.799805), house_link2:(-4132.839844, 10655)}
Player's position before change: (-26252.199219, 11936)
(-4132.839844, 10655) # pos
(-4132.839844, 10719) # new_pos
(-30385.039062, 22655) # players_position
  • Use breakpoints to follow the flow of your program. How do you transition scenes? When is `fix_player_position()` called? – hola Mar 16 '20 at 19:04
  • I've done that. Following the break points there's no unusual changes in flow, it steps through as you would expect. I have a singleton scene switcher class that swaps nodes out and sets the intended scene as the current scene, and then fix_player_position is called when added to the tree. I'm left scratching my head here – stolen_biscuit Mar 18 '20 at 04:15
  • Can you post a minimal reproducible project or code to test locally? – hola Mar 18 '20 at 16:58
  • 1
    You could try modifying the node's `position` property directly, I find it more reliable. Perhaps something in the likes of `$player.position = "the portal".position` or using `$player.transform.origin` instead. You can also add a `Vector2()` to offset the player's position by a certain value. – Breno Teodoro Mar 31 '20 at 15:16
  • That's actually what I ended up doing to fix the issue, but I forgot to update here. I'll share an answer and close this out – stolen_biscuit Apr 11 '20 at 23:51

1 Answers1

0

So I'm not sure what the actual problem was, but the solution was to replace

$player.set_global_position(new_pos)

with

$player.position = new_pos

and the code works successfully.