Movement script acting weird

Godot 4.5.1

Hi, I was trying to make a fly/swim script and I got this weird effect where I get the intended effect sometimes happens and sometimes doesn’t. Note that in the video for the first portion where direction.x = -1, I am holding A, and direction should be changing based on my camera view.

Code:

extends CharacterBody3D

var is_swimming := true

@onready var head = $Pivot
@onready var camera = $Pivot/Camera3D

const SPEED = 5.0
const JUMP_VELOCITY = 4.5
const SENSITIVITY = 0.004

func _ready() -> void:
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseMotion:
		if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
			head.rotate_y(-event.relative.x * SENSITIVITY)
			camera.rotate_x(-event.relative.y * SENSITIVITY)
			camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-50), deg_to_rad(50))

func _physics_process(delta: float) -> void:
	if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
		if Input.is_action_just_pressed("capture_mouse"):
			Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
			
		if not is_on_floor() and not is_swimming:
			velocity += get_gravity() * delta
			move_and_slide()
		return

	if Input.is_action_just_pressed("ui_cancel"):
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
	
	var direction := Vector3.ZERO
	var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_backward")
	if not is_swimming:
		if not is_on_floor():
			velocity += get_gravity() * delta
		
		if Input.is_action_just_pressed("move_up") and is_on_floor():
			velocity.y = JUMP_VELOCITY
			
		direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
		print(direction)
	else:
		#Direction gets stuck at (0.0, 0.766044, 0.642788)
		var vertical_dir := Vector3.ZERO
		if Input.is_action_pressed("move_up"):
			vertical_dir = Vector3(0,10,0)
		if Input.is_action_pressed("move_down"):
			vertical_dir = Vector3(0,-10,0)
			
		direction = (input_dir.y * camera.transform.basis.z + input_dir.x * camera.transform.basis.x + vertical_dir).normalized()
		print(direction)
	
	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
		if is_swimming:
			velocity.y = direction.y * SPEED
	else:
		velocity.x = 0.0
		velocity.z = 0.0
		if is_swimming:
			velocity.y = 0.0
	
	move_and_slide()

If the direction is supposed to be in global space then all those bases you’re taking should also be global, not local.

1 Like

Sorry for the wait before I was able to reply, thanks because that was it.

1 Like