Trouble moving and rotating an AnimatableBody3D

Godot Version

v4.5.1 Universal

Question

I’m working on getting a “paddle” (think Breakout) moving horizontally with rotation around the Z-axis (facing the camera). My frustration is that with my current approach I can only get one or the other working. I have a root Node3D with the following script attached:

extends Node3D

const SPEED = 5.0
const FOLLOW_SPEED = 4.0

@onready var movement_lead: Node3D = $MovementLead
@onready var paddle_body: AnimatableBody3D = $AnimatableBody3D

func _physics_process(delta):
	var input_vector = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var horizontal_input_direction = (transform.basis * Vector3(input_vector.x, 0, 0)).normalized()

	movement_lead.position = movement_lead.position + (horizontal_input_direction * delta * SPEED)
	var current_lead_position = movement_lead.position

	paddle_body.position = paddle_body.position.lerp(current_lead_position, delta * FOLLOW_SPEED)

	var vertical_input_direction = (transform.basis * Vector3(0, input_vector.y, 0)).normalized()
	paddle_body.rotate_z(vertical_input_direction.y * delta * SPEED)

And here is a screenshot of the hierarchy of that node (apologies if a screenshot is not the best way to share such a thing):

In the state of the script as it’s shared, the rotation works as I’d expect, but the movement does not. My idea is that the MovementLeadnode is what the player “actually” controls, and then I move the AnimatableBody3D to follow it. If I move the paddle_body.position assignment to be after the rotate_zcall, the horizontal movement works, but not the rotation.

I’m obviously showing ignorance as to how transforms, rotations, positions and Godot in general work! But, to reiterate: I’m confused as to why only the rotation or the movement works, but not both. Any thoughts? Thanks in advance!

Try using global_position instead of position

@normalized thank you for the response! I tried substituting global_position for position to no effect. I did find another solution though: introduce a new parent node for the AnimatableBody3D, and adjust the position of that, and then rotate the AnimatableBody3D independently.

Here is the updated script (the node referenced by paddle_pivot is a new Node3D that the AnimatableBody3D is a child of):

extends Node3D

const SPEED = 5.0
const FOLLOW_SPEED = 4.0

@onready var movement_lead: Node3D = $MovementLead
@onready var paddle_pivot: Node3D = $Pivot
@onready var paddle_body: AnimatableBody3D = $Pivot/AnimatableBody3D

func _physics_process(delta):
	var input_vector = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var horizontal_input_direction = (transform.basis * Vector3(input_vector.x, 0, 0)).normalized()

	movement_lead.position = movement_lead.position + (horizontal_input_direction * delta * SPEED)
	var current_lead_position = movement_lead.position

	paddle_pivot.position = paddle_pivot.position.lerp(current_lead_position, delta * FOLLOW_SPEED)

	var vertical_input_direction = (transform.basis * Vector3(0, input_vector.y, 0)).normalized()
	paddle_body.rotate_z(vertical_input_direction.y * delta * SPEED)

Here’s also a small clip of the “finished” (very primitive) product for reference in case it’s not clear what I was going for:

fixed_paddle