Mapping a virtual joystick to a gamepad joystick

Godot Version

4

Question

Hello, i want to program an on-screen virtual joystick that basically copies the exact moves of a physical gamepad joystick. I have tried to program this using input strength in 4 directions of the joystick and combining them. But this does not work smoothly and the virtual joystick ends up in a diamond shape rather than a circle. Can someone give me some tips on how to tackle this? Or is there an easier way to implement this? Thanks for your help.

Aloa natesirc,

a minimal working example:

class_name MiniJoypad extends Node2D

var width:int = 128
var inner_width:int = 32
var center:Vector2
var center_indicator:Vector2

func _ready() -> void:
	center = Vector2(
		ProjectSettings.get_setting("display/window/size/viewport_width") / 2,
		ProjectSettings.get_setting("display/window/size/viewport_height") / 2
	)

func _process(delta):
	center_indicator = Vector2(
		center.x + (width - inner_width) * Input.get_joy_axis(0, JOY_AXIS_LEFT_X),
		center.y + (width - inner_width) * Input.get_joy_axis(0, JOY_AXIS_LEFT_Y)
	)
	queue_redraw()

func _draw() -> void:
	draw_unfilled_circle(center, width, Color.WHITE)
	draw_unfilled_circle(center_indicator, inner_width, Color.WHITE)

func draw_unfilled_circle(center:Vector2, radius:float, color:Color) -> void:
	var nb_points:int = 32
	var points_arc:Array = PackedVector2Array()
	for i in range(nb_points + 1):
		var angle_point:float = deg_to_rad(0 + i * 360.0 / nb_points - 90.0)
		points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius)
	for index_point in range(nb_points):
		draw_line(points_arc[index_point], points_arc[index_point + 1], color)

Which then will look like this:
MiniJoypad

Edit: For me the gif is frozen, but context menu → open graphic in new window works like a charm.

Kind regards,
KowalewskajA

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.