Please help make my player move in the direction it's facing

Godot Version

4

Question

I’ve got the player in my first 3D game to move around, have a camera following behind them, and they can turn.

But I can’t get the player to move in the direction they are facing (after turn). Can someone please tell me how to change the last three lines of this code?

extends CharacterBody3D

var _speed = 3.0
var _gravity = ProjectSettings.get_setting("physics/3d/default_gravity");

func _physics_process(delta: float):
	handleTurn(delta)
	var input_vector = Vector2(Input.get_joy_axis(0, JOY_AXIS_LEFT_X), Input.get_joy_axis(0, JOY_AXIS_LEFT_Y))
	handleGamepadMove(delta, input_vector)
	handleKeyboardMoveIfNoGamepadInput(delta, input_vector)
	if not is_on_floor():
		velocity.y -= _gravity * delta
	move_and_slide()
	$Camera.look_at(self.position)
	
func handleTurn(delta: float):
	var right_input_x = Input.get_joy_axis(0, JOY_AXIS_RIGHT_X)
	if abs(right_input_x) > 0.1: 
		self.rotation.y += right_input_x * -5 * delta

func handleGamepadMove(delta: float, input_vector: Vector2):
	if input_vector.length() < 0.1:
		input_vector = Vector2.ZERO
	else:
		input_vector = input_vector.normalized()
	var position2 = Vector2(self.position.x * _speed * delta, self.position.z * _speed * delta)
	position2 = position2 * Transform2D(self.rotation.y, input_vector)
	self.velocity = Vector3(position2.x, self.velocity.y, position2.y)

Is it a first person controller?

I want the player to move in the direction it is facing.

velocity = basis.z * your_movement_vector

You can try this:

if input_vector.y == 1:
    velocity = transform.basis.z * speed
elif input_vector.y == -1:
    velocity = -transform.basis.z * speed

Thanks @KingGD , that code was almost correct. It works now with the code below. But why do we not multiply speed by delta? How do I keep my player speed constant when computer speeds differ without delta?

func handleGamepadMove(delta: float, input_vector: Vector2):
	if input_vector.length() < 0.1:
		input_vector = Vector2.ZERO
	else:
		input_vector = input_vector.normalized()
	if input_vector.y > 0.1:
		self.velocity = self.transform.basis.z * _speed  # * delta
	elif input_vector.y < -0.1:
		self.velocity = -self.transform.basis.z * _speed # * delta
1 Like

Yes, you can use delta

Everything works now. Question answered:

func handleGamepadMove(delta: float, input_vector: Vector2):
	if input_vector.length() < 0.1:
		input_vector = Vector2.ZERO
	else:
		input_vector = input_vector.normalized()
	var saveY = self.velocity.y
	self.velocity = \
		(self.transform.basis.z.normalized() * input_vector.y \
		+ self.transform.basis.x.normalized() * input_vector.x) \
		* _speed * delta * 10
	self.velocity.y = saveY

Ah, actually this code makes the player go forward and back, but what I really want is the player to move in the direction of the joystick, but remain facing forward.

This code moves in all directions, but going sideways is twice as fast as going forward and back. Do I need to normalize or denormalize something?

func handleGamepadMove(delta: float, input_vector: Vector2):
	if input_vector.length() < 0.1:
		input_vector = Vector2.ZERO
	else:
		input_vector = input_vector.normalized()
	var falling = self.velocity.y
	self.velocity = (self.transform.basis.z * input_vector.y + self.transform.basis.x * input_vector.x) \
		* _speed * delta * 100
	self.velocity.y = falling

If possible, show the video