GithubHelp home page GithubHelp logo

marcofaziorandom / virtual-joystick-godot Goto Github PK

View Code? Open in Web Editor NEW
582.0 16.0 62.0 542 KB

A simple virtual joystick for touchscreens, for both 2D and 3D games, with useful options.

License: MIT License

GDScript 100.00%
joystick godot gdscript touchscreen

virtual-joystick-godot's Introduction

Godot Virtual Joystick

A simple virtual joystick for touchscreens, with useful options.

GitHub Page: https://github.com/MarcoFazioRandom/Virtual-Joystick-Godot

Godot Engine: https://godotengine.org

PREVIEWS:

Easy to use:

extends Sprite2D

@export var speed : float = 100

@export var joystick_left : VirtualJoystick

@export var joystick_right : VirtualJoystick

var move_vector := Vector2.ZERO

func _process(delta: float) -> void:
	## Movement using the joystick output:
#	if joystick_left and joystick_left.is_pressed:
#		position += joystick_left.output * speed * delta

	## Movement using Input functions:
	move_vector = Vector2.ZERO
	move_vector = Input.get_vector("ui_left","ui_right","ui_up","ui_down")
	position += move_vector * speed * delta

	# Rotation:
	if joystick_right and joystick_right.is_pressed:
		rotation = joystick_right.output.angle()

OPTIONS:

  • Joystick mode:

    • Fixed: The joystick doesn't move.
    • Dynamic: Every time the joystick area is pressed, the joystick position is set on the touched position.
    • Following: When the finger moves outside the joystick area, the joystick will follow it.
  • Dead zone size: If the tip is inside this range the output is zero.

  • Clamp zone size: The max distance the tip can reach.

  • Visibility mode:

    • always: Always visible.
    • touchscreen only: Visible on touch screens only (will hide if the device has not a touchscreen).
    • when_touched: Visible only when touched.
  • Use input actions: if true the joystick will trigger the input actions created in Project -> Project Settings -> Input Map

HELP:

  • The Control parent of the joystick is the area in which the joystick can move in Dynamic mode.
  • For moving the joystick inside his area, select it, right click, turn on "Editable Children" and then change the position of the Base node.
  • With "Editable Children" turned on you can also edit the joystick textures and colors.
  • Create a CanvasLayer node and name it "UI", it'll contain all the UI elements, then add the Joystick scene as a child of the UI node and move it where you prefer.
  • An example scene is provided in the "Test" folder.

FAQ

Multitouch doesn't work / can't use two joystick at the same time:

In Godot, the input events from the mouse don't support multitouch, so make sure to have this configuration:
Project -> Project Settings -> General -> Input Devices
"emulate touch from mouse" ON
"emulate mouse from touch" OFF

The joystick doesn't work when using Input.get_vector():

This has been fixed in Godot Engine 4.2.1
Unfortunately, this a bug in the Godot engine, so the only solution for now is using Input.get_axis:
This doesn't work:

input_vector := Input.get_vector("ui_left","ui_right","ui_up","ui_down")

This works:

input_vector := Vector2.ZERO
input_vector.x = Input.get_axis("ui_left", "ui_right")
input_vector.y = Input.get_axis("ui_up", "ui_down")

virtual-joystick-godot's People

Contributors

aaronrecord avatar eawebdev avatar imp-sike avatar jack3g avatar marcofaziorandom avatar nemodreamer avatar vlaska avatar warent avatar ztc0611 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

virtual-joystick-godot's Issues

Idea suggestion for second stage jostick drag outside of circle area

Im working on a twin stick shooter and I was thinking about how to implement walking/ running switch and aiming shooting switch...

the idea is the the central joystick sticks to the bounds of the ring for the first level of control, ie. walking, but once you drag past a radius threshold, the joystick unsnaps from the rings bounds and then you enter a second stage ie, running.

The same for aiming, just pointing and holding up to a range of the circle's edge is just aiming but when you drag outside the threshold it unsnaps and now your shooting,
all the while you can still keep moving and aiming in any direction. but if you drag back to center it goes back to the first stage or if you let go.

thoughts?

Use standard addons structure

Hi, I was wondering if you can move the layout into the standard "addons/Virtual-Joystick-Godot" structure for the redistributable and use the outside structure for demos.

The folders in your project may collide with other file paths. We only use 3 folders in our project.

  1. addons
  2. <project_utils>
  3. <project>

Note:

Typically it's "addons/virtual_joystick_godot" in the Godot Engine style guide, but it's no big deal.

floating virtual joystick

on most games, there's an option for "floating joystick" where if you pressed an acceptable joystick area, the joystick position will move according to event position. it would've been great if we have this option

Idea for a 2 stage Joystick, 2 clamp zones?

I'm thinking about controls for top down games where it's twin joysticks... so Left joystick is walk direction and if you drag outside of the first clamp zone you can trigger another action, like run... then a right joystick that is aiming and when you drag out of the first clamp zone you actually shoot.

Thoughts?

joystick stuck

Hello im using virtual joystick for movement my 3d game project
when I start moving my player the joypad suddenly crashes and my character keeps running
photo_2021-12-12 18 09 13

right stick for camera rotation

Hi, I'm tryng to use your plugin for a right stick that control 3d person camera.
the pad doesn't perform any action if i set the action "look_left" "look_right" etc for the camera rotation.
using that action with a real gamepad works fine.
any suggestions?

Multi-touch support not working as expected

Currently having an issue with multi touch. I have a UI with the Joystick on the left and a button to shoot on the right. If I press the shoot button before touching the joystick the button works while operating the joystick. If I operate the joystick before pressing the button initially the button fails to execute the pressed event while using the joystick.

The screen layout:
image

The layout of the nodes:
image

Currently the joystick just prints out the angle and the button prints out fire.

Update for Godot 4

Hello, I was using your fantastic plugin in Godot 3, can you please update the code to get it working in Godot 4 please?

There are some variable renaming and the usage of setget.

Thanks for your time and effort.

Improvement: working with get_vector()

Your solution works great, but I wonder if is it possible to adapt joystick code to work also with Input.get_vector() as right now, only works with Input.get_axis()

Sample, in your own test.tscn:

	# Movement using Input functions:
	var move := Vector2.ZERO
#	move.x = Input.get_axis("ui_left", "ui_right")
#	move.y = Input.get_axis("ui_up", "ui_down")
	move = Input.get_vector("ui_left","ui_right","ui_up","ui_down") <--IT DOESN'T WORK. Joystick doesn't trigget actions
	position += move * speed * delta

Cannot disable deadzone

Setting the Deadzone to 0.0 will won't have the expected effect. The joystick and therefore also the KinematicBody2D will still only move after a certain threshold.

I spend some time trying to figure out why, but I did not manage to fix it.
However one thing I did notice is that the deadzone range is export(float, 0, 0.5) var dead_zone := 0.2
I suspected it might become an int when set to "0.0" so I changed it to export(float, 0.0, 0.5) var dead_zone := 0.0 but that made no difference.

Would love to hear your thoughts on what to do there because this is really a fantastic Godot resource, but I can't use it in my projects with a deadzone.

Joystick becomes stuck

Well I think the video describes the issue pretty much. The screenshot is from the node structure I'm using at the moment. Sorry for the wierd video resolution OBS freaked out.

2024-02-20.20-24-05.mp4

image

Invalid get index 'sie' (on base: 'TextureRect').

So when I faced with this problem I simple fixed this
in file virtual_joystick.gd 58 line:

  1. @onready var _base_radius = _base.sie * _base.get_global_transform_with_canvas().get_scale() / 2

To this:

  1. @onready var _base_radius = _base.size * _base.get_global_transform_with_canvas().get_scale() / 2

Fixed the typo "sie" -> "size"

Let me know if I was wrong

Não aparece o nó pra adicionar

o seguinte erro aparece:

Godot Engine v4.2.1.stable.official.b09f793f5 - https://godotengine.org
Vulkan API 1.3.260 - Forward Mobile - Using Vulkan Device #0: NVIDIA - NVIDIA GeForce GTX 1070

--- Debugging process stopped ---
Remove Node(s)
Attempt to open script 'res://joystick/virtual_joystick.gd' resulted in error 'File not found'.
Failed loading resource: res://joystick/virtual_joystick.gd. Make sure resources have been imported by opening the project in the editor at least once.

Is there a way to use it as a simple 4 direction 80-style joypad?

Ciao,

I was wondering if there is an easy way to use this component as a simple old style non analogic 4-way joystick, like it was the controller on a 1980s nintendo NES.

Something similar to what is displayed on a mobile browser when you open a pico8 game.

9973f21c-ec11-459e-bb17-b5fb17bcdb94

Thank you!

Scaling messes up the joystick

I tried many solutions to solve this issue, the problem is that the Control node has in my opinion an ugly and unreliable way to deal with position, scaling, pivot, anchors etc. So I didn't find a good way to solve this problem, if someone knows please let me know.
Personally I think Godot should update the Control node to be easier to deal with (for example give local and global variable of scale, make the pivot normalized between 0-1, etc.).
For now I'm taking a break with Godot and I don't know when I'll return to use it.

Diagonal use case

Hello, do you have example how to use it in the diagonal cases? Does it work with V4?

Only 8 directions when using input actions

When using input actions, using Input.get_vector() (which apparently got fixed) as well as Input.get_axis() results in vectors that are 8-directional. I updated the following methods to fix it:

func _update_joystick(touch_position: Vector2) -> void:
	var _base_radius = _get_base_radius()
	var center : Vector2 = _base.global_position + _base_radius
	var vector : Vector2 = touch_position - center
	vector = vector.limit_length(clampzone_size)
	
	if joystick_mode == Joystick_mode.FOLLOWING and touch_position.distance_to(center) > clampzone_size:
		_move_base(touch_position - vector)
	
	_move_tip(center + vector)
	
	if vector.length_squared() > deadzone_size * deadzone_size:
		is_pressed = true
		output = (vector - (vector.normalized() * deadzone_size)) / (clampzone_size - deadzone_size)

		if use_input_actions:
			if output.x > 0:
				Input.action_press(action_right, output.x)
				Input.action_release(action_left)
			else:
				Input.action_press(action_left, -output.x)
				Input.action_release(action_right)

			if output.y > 0:
				Input.action_press(action_down, output.y)
				Input.action_release(action_up)
			else:
				Input.action_press(action_up, -output.y)
				Input.action_release(action_down)

	else:
		is_pressed = false
		output = Vector2.ZERO
		if use_input_actions:
			_reset_input()

func _reset():
	is_pressed = false
	output = Vector2.ZERO
	_touch_index = -1
	_tip.modulate = _default_color
	_base.position = _base_default_position
	_tip.position = _tip_default_position
	if use_input_actions:
		_reset_input()

func _reset_input():
	for action in [action_left, action_right, action_down, action_up]:
		Input.action_release(action)

Cannot Get This To Work

Hello, if I open your files, the joystick works fine. If I create a new project and import your test scene, the joystick won't move. Am I missing some setting?

Input processing Issue

The joystick is working with "Use Input Actions".

Emulate touch from mouse is disabled. Emulate mouse from touch is enabled for menu and player action buttons e.g. the attack button.

I have a TextureButton with the following code:

func _on_AttackButton_down():
	Input.action_press("ui_attack")

func _on_AttackButton_up():
	Input.action_release("ui_attack")

When using just keyboard input without the Joystick and TextureButton, I can move and attack simultaneously. When using the Joystick/TextureButton on a mobile device to move and attack, I can only do one or the other. Sometimes if I press & hold the TextureButton first to attack and then touch/move the joystick I can do both (Doing movement with joystick first then pressing attack does not work). I wonder if this is because of the button and the need for mouse emulation so the button works when touched.

Any ideas? Thanks in advance!

Jumping doesn't work only on android.

The joystick works for moving left and right, but jumping doesn't work for some reason. Disabling Emulate Mouse From Touch didn't fix it. There is only one instance of the joystick on the screen, so it's not a multitouch issue.

Everything does work properly on PC. But not on Android. Could this be an issue with game logic? But why would it still work on PC?

image
image
image

Virtual joystick REALLY prefers diagonal movement

Frustratingly, the only issues with my EXACT issue are closed without any solution...

Anyways, I am using this plugin on a 3D game to move the player around. The problem is that it is nearly impossible to move directly forward, backward, etc. It's doable, but once it's moved even a pixel to the left or right the player starts moving diagonally, making it super annoying to move around the game.

I have not modified the joysticks script in anyway either. If there's any way to better divide up the "input zones" that would be great.

Move issues

the joystick works on a new project but imported into mine it does not move even without resizing it

unusable, cos of weird button directions..?

just had a quick look at this to see if it'd be useful, but instead of buttons foe left, right, up and downit has buttons diagonal directions!?
which games move in diagonals ?

Increase measurement error for Joystick's corner values

If user wants to go straight sideways or up/down the joystick still works only in diagonal, because this check

if output.x < -0:
    Input.action_press(action_left, -output.x)
elif Input.is_action_pressed(action_left):
    Input.action_release(action_left)

returns true even for the smallest values and it's impossible to hit straight on 0

How about increasing value in check to 0.1 / -0.1?

This works perfectly

func _update_input_actions():
	if output.x < -0.1:
		Input.action_press(action_left, -output.x)
	elif Input.is_action_pressed(action_left):
		Input.action_release(action_left)
	if output.x > 0.1:
		Input.action_press(action_right, output.x)
	elif Input.is_action_pressed(action_right):
		Input.action_release(action_right)
	if output.y < -0.1:
		Input.action_press(action_up, -output.y)
	elif Input.is_action_pressed(action_up):
		Input.action_release(action_up)
	if output.y > 0.1:
		Input.action_press(action_down, output.y)
	elif Input.is_action_pressed(action_down):
		Input.action_release(action_down)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.