Axis-based unintentional strafing, not sure how to fix.

Godot Version

v4.5.1.stable.arch_linux

Question

Movement relies on transform.basis’s basis. therefore making a mouse-based visual navigation in yaw rotation cause a axis-based strafing that’s reverse-relative to player’s movement input.

I don’t know what to do from here, it took hours to do something I want but if it comes out to this, should I declare this algorithm as unusable?

extends CharacterBody3D
@onready var dbg_label: Label = $"../Control/dbgLabel"
@onready var dbg_label_2: Label = $"../Control/dbgLabel2"

const SPEED = 5.0
const JUMP_VELOCITY = 4.5
const ACCEL_DECEL = 0.3
var mouse_sensitivity = 0.003

func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("move_jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir := Input.get_vector("move_left", "move_right", "move_fw", "move_bw")
	var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if is_on_floor():
		if direction:
			# In the `velocity.(axis)` variable, current velocity has to `move_toward`s the 
			# direction's relative axis `direction.(axis)` to it's maximal player
			# speed `direction.(axis) * SPEED`every value in the ACCEL_DECEL constant variable
			
			velocity.x = move_toward(velocity.x, direction.x * SPEED, ACCEL_DECEL)
			velocity.z = move_toward(velocity.z, direction.z * SPEED, ACCEL_DECEL)
		else:
			velocity.x = move_toward(velocity.x, 0.0, ACCEL_DECEL)
			velocity.z = move_toward(velocity.z, 0.0, ACCEL_DECEL)

	move_and_slide()
	dbg_label.text = str(transform.basis)
	dbg_label_2.text = str(velocity)
	
func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	
func _input(event: InputEvent) -> void:
	if event is InputEventMouseMotion:
		rotate_y(-event.relative.x * mouse_sensitivity)

Not completely sure if that’s the issue you’re describing, but don’t use move_toward() on x and z separately. Try:

velocity = velocity.move_toward( Vector3(direction.x * SPEED, velocity.y, direction.z * SPEED), ACCEL_DECEL )
1 Like

Hi tameshita!

Your code doesn’t look too complicated yet, so I’m sure it can be fixed. I’m not quite sure, if you could make your code achieve what you want or if you couldn’t. What is it that you want exactly?

Do not forget that in the end when everything is working as intended, you should include delta as a factor for your direction.x and direction.z movement as well.

Kind regards :four_leaf_clover:

Someone else got the solution already, but thanks anyways

This works well, even If I’m having kind of a hard time understanding the code.

I noticed that the player speed will be reduced depending on the rotation though, maybe I shouldn’t do this at all…

Oh nevermind It works fine, i’m just an idiot