• Godot Help
  • Getting the position of an instanced scene after moving it

Hi,

I'm making a 2D platformer with ladders. As I begin to build the ladder mechanic i'm running into a few issues.
The Ladder's root node is an Area2D, with a Sprite and CollisionShape2D. The scene is autoloaded to make it accessable to other scripts. The CollisionShape2D is set to 'Make unique' allowing me to scale the ladder's sprite with it's collision shape.
I'm centering the Player on the ladder when he collides with the Ladder.
Getting the reference for the location of the Ladder in the Ladder's script:

var ladder_position = Vector2()
func _ready() -> void:
ladder_position.x = self.global_position.x

In the Player's script I use the position of the Ladder and apply it to the Player:

func _on_Ladder_on_ladder() -> void:
self.global_position.x = Ladder.ladder_position.x

I'll need to move the instanced Ladder's to the relevant location on my level map. But the problem is that the location the Player receives is the one before the Ladder is moved. I don't know how to get the current position of the Ladder.
Currently when the Player collides with the ladder, it is set to the top left corner of the screen (0,0).
What should I do?

You can access any variable you want at any time (as long as you have a reference to the node). Like this:

func _on_Ladder_on_ladder() -> void:
    self.global_position.x = Ladder.global_position.x

    cybereality I don't know what you mean, you've just duplicated my code. I didn't ask about accessing variables.

    Sorry I didn't see your change 😉 However it still has the same result. Only the original position of the Ladder is available, not it's current position where it has been dragged to on the main scene level.

    Your player script is getting called before the ladder script and it's in the wrong order. Is that what is happening?

    You might be able to create a function in the ladder script, that the player script calls that will update the position of the ladder. Then get the position of ladder.

      newmodels Thanks for the info. I don't know if the Player is called before the Ladder script. The Ladders are all in the Main Scene Tree along with the Player when the game starts.

      I'm not sure how to create a function that will update the position of the Ladder - not something I've come across in any tutorials.

        JayBanana

        How is the ladder instanced? It's hard to know the problem without being able to see the source code.

        The ladder is instanced, and then it's position is set?
        Is the player reaching the ladder, and then the ladder is instanced?

          ok reading your post again, and I can see the problem more clearly.

          How are you instancing the ladder in code, and then setting it's position?

          newmodels The Ladder has it's own scene, Area2D, Sprite and CollisionShape2D.
          The Ladder/s are added to the Main Game Level Scene by the 'Instance Child Scene' Button. The ladders are stationary after I've placed them where I want them.

          When I run the game and the Player collides with the Ladders from my script, he's then taken to 0 (Zero) on the X axis. I'm assuming that this is because Godot isn't seeing the current location of the Ladder/s, only the original positon before I placed them where I wanted.

          (Note: I made the children editable in the main scene to be clearer)

          It seems like the position variable you are using is getting assigned before the ladder has it's real position. cyberreality suggesting using the ladders node variables, rather than the self one you had made, but.

          You can put that assignment into a function, and then use call deferred to call the function that makes the assignment. Then it should be updated with it's position.

          Or, you could call that function instead from player, but it would be better to just fetch the nodes variables.

          newmodels I'm not sure what do here in code. I know how to create a function and call one (if it's accessable), but I'm not sure about the rest.

            JayBanana

            In the function, you just want to do the same thing in the _ready() function. And then make player call that function, before fetching position.

              newmodels Are you saying I should use the _ready() function in the Ladder's script?

              I already have that:

              var ladder_position = Vector2()
              func _ready() -> void:
              ladder_position.x = self.global_position.x

              Just in case it affects anything, I have the Ladder scene set to autoload.

              add the function to the ladder script.

              func update_position():
              ladder_position.x = self.global_position.x
              pass

              Then in your player script, call the function before getting Ladder.ladder_position.x

                newmodels Thanks for the help, however it is behaving exactly the same with your suggestion. The Player is still changing location to the original positon of the Ladder.

                Do you know if by me autoloading the Ladder scene whether this is affecting the result?

                It's getting to the point that I might not be able to include ladders in a game until I work out what's going on.

                Maybe you need to get the variable from the transform? in 3d, I would get the position vector from the transform using something like this...

                var currloc= self.global_transform.position

                The player may be colliding with the collision shape, not the ladder itself. It depends how you are detecting the collision. Can you post what you signal code/connection is doing? Also, using an Autoload is not the best method, that may be part of the problem. You can detect generic collision, check if it is a ladder, and then move to the desired position. This is needed if there are more than 1 ladder.

                I have started using Signals instead of autoload for the ladders, this has fixed my issues - I just didn't know how to fully use them 😉