Initial commit
BIN
joystick/previews/gitpreview.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
34
joystick/previews/gitpreview.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b2vis61tr0j0j"
|
||||
path="res://.godot/imported/gitpreview.png-ec153c306c5152ca4b5b1f0cefb68e3c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/previews/gitpreview.png"
|
||||
dest_files=["res://.godot/imported/gitpreview.png-ec153c306c5152ca4b5b1f0cefb68e3c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
joystick/previews/icon.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
34
joystick/previews/icon.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dqlnk87ubowrk"
|
||||
path="res://.godot/imported/icon.png-324c050649ddbd50ea0d7a9cc738a782.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/previews/icon.png"
|
||||
dest_files=["res://.godot/imported/icon.png-324c050649ddbd50ea0d7a9cc738a782.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
joystick/previews/preview1.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
34
joystick/previews/preview1.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://0xvr5pp3p3ab"
|
||||
path="res://.godot/imported/preview1.png-d4c4e981b042b85f31fe17ca28e82247.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/previews/preview1.png"
|
||||
dest_files=["res://.godot/imported/preview1.png-d4c4e981b042b85f31fe17ca28e82247.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
joystick/previews/preview2.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
34
joystick/previews/preview2.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cdetlhwaywl5l"
|
||||
path="res://.godot/imported/preview2.png-81dc3b7e24520b798753905eeb475d3a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/previews/preview2.png"
|
||||
dest_files=["res://.godot/imported/preview2.png-81dc3b7e24520b798753905eeb475d3a.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
joystick/previews/preview3.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
34
joystick/previews/preview3.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://7i3tk35p2d3g"
|
||||
path="res://.godot/imported/preview3.png-388abb38ce4b6197827ca76ef0b2e8de.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/previews/preview3.png"
|
||||
dest_files=["res://.godot/imported/preview3.png-388abb38ce4b6197827ca76ef0b2e8de.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
joystick/textures/joystick_base_outline.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
34
joystick/textures/joystick_base_outline.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bm30au8mjfc2f"
|
||||
path="res://.godot/imported/joystick_base_outline.png-483e8f1ac02a5b9a594f81d7e341a76f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/textures/joystick_base_outline.png"
|
||||
dest_files=["res://.godot/imported/joystick_base_outline.png-483e8f1ac02a5b9a594f81d7e341a76f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
joystick/textures/joystick_tip.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
34
joystick/textures/joystick_tip.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bkvmydfn5saxg"
|
||||
path="res://.godot/imported/joystick_tip.png-3a18c9ea76fb1ca4d2905a9a7401093a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/textures/joystick_tip.png"
|
||||
dest_files=["res://.godot/imported/joystick_tip.png-3a18c9ea76fb1ca4d2905a9a7401093a.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
joystick/textures/joystick_tip_arrows.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
34
joystick/textures/joystick_tip_arrows.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dt13r06u87fib"
|
||||
path="res://.godot/imported/joystick_tip_arrows.png-c9482441a78cf839baf32238aae88b91.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://joystick/textures/joystick_tip_arrows.png"
|
||||
dest_files=["res://.godot/imported/joystick_tip_arrows.png-c9482441a78cf839baf32238aae88b91.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
165
joystick/virtual_joystick.gd
Normal file
@@ -0,0 +1,165 @@
|
||||
class_name VirtualJoystick
|
||||
|
||||
extends Control
|
||||
|
||||
## A simple virtual joystick for touchscreens, with useful options.
|
||||
## Github: https://github.com/MarcoFazioRandom/Virtual-Joystick-Godot
|
||||
|
||||
# EXPORTED VARIABLE
|
||||
|
||||
## The color of the button when the joystick is pressed.
|
||||
@export var pressed_color := Color.GRAY
|
||||
|
||||
## If the input is inside this range, the output is zero.
|
||||
@export_range(0, 200, 1) var deadzone_size : float = 10
|
||||
|
||||
## The max distance the tip can reach.
|
||||
@export_range(0, 500, 1) var clampzone_size : float = 75
|
||||
|
||||
enum 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.
|
||||
}
|
||||
|
||||
## If the joystick stays in the same position or appears on the touched position when touch is started
|
||||
@export var joystick_mode := Joystick_mode.FIXED
|
||||
|
||||
enum Visibility_mode {
|
||||
ALWAYS, ## Always visible
|
||||
TOUCHSCREEN_ONLY ## Visible on touch screens only
|
||||
}
|
||||
|
||||
## If the joystick is always visible, or is shown only if there is a touchscreen
|
||||
@export var visibility_mode := Visibility_mode.ALWAYS
|
||||
|
||||
## If true, the joystick uses Input Actions (Project -> Project Settings -> Input Map)
|
||||
@export var use_input_actions := true
|
||||
|
||||
@export var action_left := "ui_left"
|
||||
@export var action_right := "ui_right"
|
||||
@export var action_up := "ui_up"
|
||||
@export var action_down := "ui_down"
|
||||
|
||||
# PUBLIC VARIABLES
|
||||
|
||||
## If the joystick is receiving inputs.
|
||||
var is_pressed := false
|
||||
|
||||
# The joystick output.
|
||||
var output := Vector2.ZERO
|
||||
|
||||
# PRIVATE VARIABLES
|
||||
|
||||
var _touch_index : int = -1
|
||||
|
||||
@onready var _base := $Base
|
||||
@onready var _tip := $Base/Tip
|
||||
|
||||
@onready var _base_default_position : Vector2 = _base.position
|
||||
@onready var _tip_default_position : Vector2 = _tip.position
|
||||
|
||||
@onready var _default_color : Color = _tip.modulate
|
||||
|
||||
# FUNCTIONS
|
||||
|
||||
func _ready() -> void:
|
||||
if not DisplayServer.is_touchscreen_available() and visibility_mode == Visibility_mode.TOUCHSCREEN_ONLY:
|
||||
hide()
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventScreenTouch:
|
||||
if event.pressed:
|
||||
if _is_point_inside_joystick_area(event.position) and _touch_index == -1:
|
||||
if joystick_mode == Joystick_mode.DYNAMIC or joystick_mode == Joystick_mode.FOLLOWING or (joystick_mode == Joystick_mode.FIXED and _is_point_inside_base(event.position)):
|
||||
if joystick_mode == Joystick_mode.DYNAMIC or joystick_mode == Joystick_mode.FOLLOWING:
|
||||
_move_base(event.position)
|
||||
_touch_index = event.index
|
||||
_tip.modulate = pressed_color
|
||||
_update_joystick(event.position)
|
||||
get_viewport().set_input_as_handled()
|
||||
elif event.index == _touch_index:
|
||||
_reset()
|
||||
get_viewport().set_input_as_handled()
|
||||
elif event is InputEventScreenDrag:
|
||||
if event.index == _touch_index:
|
||||
_update_joystick(event.position)
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
func _move_base(new_position: Vector2) -> void:
|
||||
_base.global_position = new_position - _base.pivot_offset * get_global_transform_with_canvas().get_scale()
|
||||
|
||||
func _move_tip(new_position: Vector2) -> void:
|
||||
_tip.global_position = new_position - _tip.pivot_offset * _base.get_global_transform_with_canvas().get_scale()
|
||||
|
||||
func _is_point_inside_joystick_area(point: Vector2) -> bool:
|
||||
var x: bool = point.x >= global_position.x and point.x <= global_position.x + (size.x * get_global_transform_with_canvas().get_scale().x)
|
||||
var y: bool = point.y >= global_position.y and point.y <= global_position.y + (size.y * get_global_transform_with_canvas().get_scale().y)
|
||||
return x and y
|
||||
|
||||
func _get_base_radius() -> Vector2:
|
||||
return _base.size * _base.get_global_transform_with_canvas().get_scale() / 2
|
||||
|
||||
func _is_point_inside_base(point: Vector2) -> bool:
|
||||
var _base_radius = _get_base_radius()
|
||||
var center : Vector2 = _base.global_position + _base_radius
|
||||
var vector : Vector2 = point - center
|
||||
if vector.length_squared() <= _base_radius.x * _base_radius.x:
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
|
||||
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)
|
||||
else:
|
||||
is_pressed = false
|
||||
output = Vector2.ZERO
|
||||
|
||||
if use_input_actions:
|
||||
if output.x > 0:
|
||||
if Input.is_action_pressed(action_left):
|
||||
Input.action_release(action_left)
|
||||
_update_input_action(action_right, output.x)
|
||||
else:
|
||||
if Input.is_action_pressed(action_right):
|
||||
Input.action_release(action_right)
|
||||
_update_input_action(action_left, -output.x)
|
||||
|
||||
if output.y > 0:
|
||||
if Input.is_action_pressed(action_up):
|
||||
Input.action_release(action_up)
|
||||
_update_input_action(action_down, output.y)
|
||||
else:
|
||||
if Input.is_action_pressed(action_down):
|
||||
Input.action_release(action_down)
|
||||
_update_input_action(action_up, -output.y)
|
||||
|
||||
func _update_input_action(action:String, value:float):
|
||||
if value > InputMap.action_get_deadzone(action):
|
||||
Input.action_press(action, value)
|
||||
elif Input.is_action_pressed(action):
|
||||
Input.action_release(action)
|
||||
|
||||
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:
|
||||
for action in [action_left, action_right, action_down, action_up]:
|
||||
if Input.is_action_pressed(action) or Input.is_action_just_pressed(action):
|
||||
Input.action_release(action)
|
||||
51
joystick/virtual_joystick.tscn
Normal file
@@ -0,0 +1,51 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://dmr0fcamx7t56"]
|
||||
|
||||
[ext_resource type="Script" path="res://joystick/virtual_joystick.gd" id="1_8x4dy"]
|
||||
[ext_resource type="Texture2D" uid="uid://bm30au8mjfc2f" path="res://joystick/textures/joystick_base_outline.png" id="2_jhjs2"]
|
||||
[ext_resource type="Texture2D" uid="uid://dt13r06u87fib" path="res://joystick/textures/joystick_tip_arrows.png" id="3_3etdg"]
|
||||
|
||||
[node name="Virtual Joystick" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 2
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -308.0
|
||||
offset_right = 300.0
|
||||
offset_bottom = -8.0
|
||||
grow_vertical = 0
|
||||
script = ExtResource("1_8x4dy")
|
||||
|
||||
[node name="Base" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -100.0
|
||||
offset_top = -100.0
|
||||
offset_right = 100.0
|
||||
offset_bottom = 100.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
pivot_offset = Vector2(100, 100)
|
||||
mouse_force_pass_scroll_events = false
|
||||
texture = ExtResource("2_jhjs2")
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="Tip" type="TextureRect" parent="Base"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -50.0
|
||||
offset_top = -50.0
|
||||
offset_right = 50.0
|
||||
offset_bottom = 50.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
pivot_offset = Vector2(50, 50)
|
||||
texture = ExtResource("3_3etdg")
|
||||
stretch_mode = 5
|
||||