Hello,
I am making a game where player can swap places with selected one of 3 statues in level. Now I am stuck on issue where two objects when switching places moves slightly on X axis.

This is current switch function on player script:

I have tried many options, like using local position, global position, transform.origin. I have also tried messing with collision shapes and pivots. I found similar issues online that includes pivot and parents influence but it doesn't seem to be an issue in this project. Parent object is Node2D with 0,0 position. Objects root node is CharacterBody2D. Can anyone can help because I cant find what is causing this?

  • 1vanThe8ear You're doing the switch in the middle of the physics frame i.e. between two character's _physics_process() execution. From the perspective of the physics engine, this causes an overlap because one character's position is updated this frame while the other's is yet to be updated next frame. Since both characters are calling move_and_silde() and are setup to check/resolve collisions with each other, the engine tries to resolve this overlap and hence displaces the characters. To confuse things more, you're calling the swap from _process() while running _physics_process() at the same time.

    First, eliminate _process() from the player script and put the code in _physics_process(), and second, defer the swap to after the physics frame has been fully processed:

    func _physics_process(delta):
    	if Input.is_action_just_pressed("player_switch_places"):
    		call_deferred("SwitchPlaces")
    
    	# the rest of it

    Btw you shouldn't have everything colliding on default layer 1. Instead, separate character/character and character/tiles collisions into different collision layers.

Hard to tell without seeing the node setup. Can you make a minimal project that replicates the problem and post it here?

    xyz

    toh-mini.zip
    168kB

    Controls are arrow keys, space, S(switch places)

    • xyz replied to this.

      1vanThe8ear You're doing the switch in the middle of the physics frame i.e. between two character's _physics_process() execution. From the perspective of the physics engine, this causes an overlap because one character's position is updated this frame while the other's is yet to be updated next frame. Since both characters are calling move_and_silde() and are setup to check/resolve collisions with each other, the engine tries to resolve this overlap and hence displaces the characters. To confuse things more, you're calling the swap from _process() while running _physics_process() at the same time.

      First, eliminate _process() from the player script and put the code in _physics_process(), and second, defer the swap to after the physics frame has been fully processed:

      func _physics_process(delta):
      	if Input.is_action_just_pressed("player_switch_places"):
      		call_deferred("SwitchPlaces")
      
      	# the rest of it

      Btw you shouldn't have everything colliding on default layer 1. Instead, separate character/character and character/tiles collisions into different collision layers.

        xyz
        Thank you so much it worked. I just started using godot so I was not aware of how process methods work.