Capturing joypadmotion of right stick to move like mouse?

Godot Version

4.5 Stable Mac OS

Question

Hello I’m trying to figure out how to capture movement of right joystick on xbox controller to emulate movement of mouse cursor .

current code working with mouse capturing ( from GameDev course )

extends CharacterBody3D


const SPEED = 5.0
const JUMP_VELOCITY = 4.5


var _look := Vector2.ZERO

@export var mouse_sensitivity: float = 0.00075
@export var min_boundry: float = -60
@export var max_boundry: float = 10
@export var animation_decay: float = 20.0

@onready var horizontal_pivot: Node3D = $HorizontalPivot
@onready var vertical_pivot: Node3D = $HorizontalPivot/VerticalPivot
@onready var rig_pivot: Node3D = $RigPivot
@onready var rig: Node3D = $RigPivot/Rig




func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	
func _physics_process(delta: float) -> void:
	frame_camera_rotation()
	
	if not is_on_floor():
		velocity += get_gravity() * delta

	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY
		
	var direction = get_movement_direction()
	rig.update_animation_tree(direction)
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
		look_toward_direction(direction, delta)
		
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)

	move_and_slide()

func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("esc"):
		if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
			Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
		else:
			Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
		
	if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
		if event is InputEventMouseMotion:
			_look += -event.relative * mouse_sensitivity

func get_movement_direction() -> Vector3 :
	var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
	var input_vector := Vector3(input_dir.x, 0, input_dir.y).normalized()
	return horizontal_pivot.global_transform.basis * input_vector

func frame_camera_rotation() -> void :
	horizontal_pivot.rotate_y(_look.x)
	vertical_pivot.rotate_x(_look.y)
	
	vertical_pivot.rotation.x = clampf(
		vertical_pivot.rotation.x,
		deg_to_rad(min_boundry),
		deg_to_rad(max_boundry)
		)
	
	_look = Vector2.ZERO
	

func look_toward_direction(direction: Vector3, delta: float) -> void :
	var target_transform := rig_pivot.global_transform.looking_at(
		rig_pivot.global_position + direction, Vector3.UP, true 
	)
	rig_pivot.global_transform = rig_pivot.global_transform.interpolate_with(
		target_transform,
		1.0 - exp(-animation_decay * delta)
	)
	

What have you tried? What does not work?

Check this: Input — Godot Engine (stable) documentation in English

1 Like

I have tried to add this


var look_x := Input.get_joy_axis(0, JOY_AXIS_RIGHT_X)
	var look_y := Input.get_joy_axis(0, JOY_AXIS_RIGHT_Y)
	if abs(look_x) > 0.15 or abs(look_y) > 0.15:
		look_y = -look_y
		_look += Vector2(look_x, look_y) * controller_sensitivity * delta

	

The docs recommend to setup input actions first for the joystick.

You can get a full motion vector from the joystick with:

Input.get_vector("move_left", "move_right", "move_forward", "move_back")
1 Like

The input for walk is fine , it’s about smoothing camera rotation via rest of the code , character movement is assigned to left stick , and right do camera rotation same as mouse movement , plus B/esc is for stop capturing mouse .

This is played with Xbox controller via USB-C on Mac .