Seems like I didn’t explain well what I’m trying to do here.
To implement the desired gameplay logic, an object needs to move_and_collide, check the result and then move_and_collide again depending on the result, all within the same frame.
From what I can tell, calling move_and_collide multiple times in a frame won’t work.
In the following example, move_and_collide is being called twice and the second move_and_collide doesn’t seem to start from where previous one ended.
Here’s the code that I tested and output that I got:
extends Node3D
func _physics_process(delta: float) -> void:
print()
print(Engine.get_physics_frames(), "| ", name, " @ ", position)
if Engine.get_physics_frames() == 3:
get_tree().quit()
var delta_move := Vector3.FORWARD * delta
var a : AnimatableBody3D = get_node(".") as AnimatableBody3D
if a:
var p := position
var k : KinematicCollision3D
var t : Vector3
print("> move:", p)
k = a.move_and_collide(delta_move)
t = k.get_travel() if k else delta_move
p += t
k = a.move_and_collide(delta_move)
t = k.get_travel() if k else delta_move
print("< move:", p + t)
else:
print("> move:", position)
position += delta_move
position += delta_move
print("< move:", position)
1| Node3D @ (0.0, 0.0, 0.0)
> move:(0.0, 0.0, 0.0)
< move:(0.0, 0.0, -0.033333)
1| AnimatableBody3D @ (0.0, 0.0, 0.0)
> move:(0.0, 0.0, 0.0)
< move:(0.0, 0.0, -0.033333)
2| Node3D @ (0.0, 0.0, -0.033333)
> move:(0.0, 0.0, -0.033333)
< move:(0.0, 0.0, -0.066667)
2| AnimatableBody3D @ (0.0, 0.0, -0.016667)
> move:(0.0, 0.0, -0.016667)
< move:(0.0, 0.0, -0.05)
3| Node3D @ (0.0, 0.0, -0.066667)
> move:(0.0, 0.0, -0.066667)
< move:(0.0, 0.0, -0.1)
3| AnimatableBody3D @ (0.0, 0.0, -0.033333)
> move:(0.0, 0.0, -0.033333)
< move:(0.0, 0.0, -0.066667)