Add touch screen support for 3d/platformer (#1128)

Update touch_screen_ui.gd
This commit is contained in:
Shahriar Labib
2025-10-02 23:47:00 +06:00
committed by GitHub
parent af2b9b1f30
commit 84ac7b40a6
52 changed files with 2189 additions and 286 deletions

View File

@@ -10,6 +10,9 @@ Renderer: Forward+
Check out this demo on the asset library: https://godotengine.org/asset-library/asset/2748
This project uses Virtual joystick add-on by [`Marco F`](https://github.com/MarcoFazioRandom) for touch screen input.
Check it out: https://godotengine.org/asset-library/asset/1787
## Screenshots
![Screenshot](screenshots/platformer.webp)

View File

@@ -1,6 +1,6 @@
[gd_scene load_steps=19 format=3 uid="uid://dfxo2jwbj4aeh"]
[ext_resource type="Script" uid="uid://c2pvqnv0idykh" path="res://coin/coin.gd" id="1"]
[ext_resource type="Script" path="res://coin/coin.gd" id="1"]
[ext_resource type="AudioStream" uid="uid://b23l5nfatq2d2" path="res://coin/sound_coin.wav" id="2"]
[ext_resource type="Material" uid="uid://dp0bangabfrg" path="res://coin/coin_material.tres" id="2_n0rbc"]
[ext_resource type="Texture2D" uid="uid://y3opjgnv67r8" path="res://particle.webp" id="3"]
@@ -180,9 +180,9 @@ tracks/4/keys = {
[sub_resource type="AnimationLibrary" id="AnimationLibrary_7v453"]
_data = {
&"RESET": SubResource("Animation_r4jod"),
&"spin": SubResource("3"),
&"take": SubResource("4")
"RESET": SubResource("Animation_r4jod"),
"spin": SubResource("3"),
"take": SubResource("4")
}
[sub_resource type="SphereShape3D" id="5"]
@@ -236,7 +236,6 @@ mesh = SubResource("QuadMesh_kqa4x")
surface_material_override/0 = SubResource("StandardMaterial3D_7q0mq")
[node name="Animation" type="AnimationPlayer" parent="."]
callback_mode_process = 0
libraries = {
"": SubResource("AnimationLibrary_7v453")
}

File diff suppressed because it is too large Load Diff

View File

@@ -437,8 +437,8 @@ axis_lock_angular_y = true
axis_lock_angular_z = true
physics_material_override = SubResource("1")
custom_integrator = true
max_contacts_reported = 5
contact_monitor = true
max_contacts_reported = 5
script = ExtResource("1")
[node name="Enemy" parent="." instance=ExtResource("2_qf8n3")]
@@ -448,13 +448,13 @@ bones/1/position = Vector3(-5.04871e-28, 0.661877, 0)
bones/1/rotation = Quaternion(0.707107, -2.48537e-07, -1.95408e-07, 0.707107)
bones/2/position = Vector3(-3.87449e-08, 0.475726, -0.0617121)
bones/3/position = Vector3(0.913587, 0.661877, 0.631826)
bones/3/rotation = Quaternion(1, 0, 7.54979e-08, -1.05879e-22)
bones/3/rotation = Quaternion(1, -2.49197e-38, 7.54979e-08, -1.05879e-22)
bones/5/position = Vector3(-0.913587, 0.661877, 0.631826)
bones/5/rotation = Quaternion(1, 0, 7.54979e-08, -1.05879e-22)
bones/5/rotation = Quaternion(1, -2.49197e-38, 7.54979e-08, -1.05879e-22)
bones/7/position = Vector3(1.05436, 0.661877, -0.654576)
bones/7/rotation = Quaternion(1, 0, 7.54979e-08, -1.05879e-22)
bones/7/rotation = Quaternion(1, -2.49197e-38, 7.54979e-08, -1.05879e-22)
bones/9/position = Vector3(-1.05436, 0.661877, -0.654576)
bones/9/rotation = Quaternion(1, 0, 7.54979e-08, -1.05879e-22)
bones/9/rotation = Quaternion(1, -2.49197e-38, 7.54979e-08, -1.05879e-22)
[node name="RayFloor" type="RayCast3D" parent="Enemy/Skeleton" index="1"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.643772, 0.803052)
@@ -465,11 +465,11 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.643772, 0.310413)
target_position = Vector3(0, 0, 1.5)
[node name="AnimationPlayer" parent="Enemy" index="1"]
autoplay = "walk"
libraries = {
"": SubResource("AnimationLibrary_f4l5d"),
"extra": SubResource("AnimationLibrary_q27i1")
}
autoplay = "walk"
[node name="Sphere1" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.74185, 0.267137)

View File

@@ -1,221 +0,0 @@
[preset.0]
exclude_filter=""
export_filter="all_resources"
include_filter=""
name="Linux/X11"
patch_list=PackedStringArray( )
platform="Linux/X11"
runnable=true
[preset.0.options]
binary_format/64_bits=true
custom_template/debug=""
custom_template/release=""
texture_format/etc=false
texture_format/etc2=false
texture_format/s3tc=true
[preset.1]
exclude_filter=""
export_filter="all_resources"
include_filter=""
name="Android"
patch_list=PackedStringArray( )
platform="Android"
runnable=true
[preset.1.options]
apk_expansion/SALT=""
apk_expansion/enable=false
apk_expansion/public_key=""
architecture/arm=true
architecture/x86=false
command_line/extra_args=""
custom_package/debug=""
custom_package/release=""
keystore/release=""
keystore/release_password=""
keystore/release_user=""
one_click_deploy/clear_previous_install=true
package/icon=""
package/name=""
package/signed=true
package/unique_name="org.godotengine.$genname"
permissions/access_checkin_properties=false
permissions/access_coarse_location=false
permissions/access_fine_location=false
permissions/access_location_extra_commands=false
permissions/access_mock_location=false
permissions/access_network_state=false
permissions/access_surface_flinger=false
permissions/access_wifi_state=false
permissions/account_manager=false
permissions/add_voicemail=false
permissions/authenticate_accounts=false
permissions/battery_stats=false
permissions/bind_accessibility_service=false
permissions/bind_appwidget=false
permissions/bind_device_admin=false
permissions/bind_input_method=false
permissions/bind_nfc_service=false
permissions/bind_notification_listener_service=false
permissions/bind_print_service=false
permissions/bind_remoteviews=false
permissions/bind_text_service=false
permissions/bind_vpn_service=false
permissions/bind_wallpaper=false
permissions/bluetooth=false
permissions/bluetooth_admin=false
permissions/bluetooth_privileged=false
permissions/brick=false
permissions/broadcast_package_removed=false
permissions/broadcast_sms=false
permissions/broadcast_sticky=false
permissions/broadcast_wap_push=false
permissions/call_phone=false
permissions/call_privileged=false
permissions/camera=false
permissions/capture_audio_output=false
permissions/capture_secure_video_output=false
permissions/capture_video_output=false
permissions/change_component_enabled_state=false
permissions/change_configuration=false
permissions/change_network_state=false
permissions/change_wifi_multicast_state=false
permissions/change_wifi_state=false
permissions/clear_app_cache=false
permissions/clear_app_user_data=false
permissions/control_location_updates=false
permissions/delete_cache_files=false
permissions/delete_packages=false
permissions/device_power=false
permissions/diagnostic=false
permissions/disable_keyguard=false
permissions/dump=false
permissions/expand_status_bar=false
permissions/factory_test=false
permissions/flashlight=false
permissions/force_back=false
permissions/get_accounts=false
permissions/get_package_size=false
permissions/get_tasks=false
permissions/get_top_activity_info=false
permissions/global_search=false
permissions/hardware_test=false
permissions/inject_events=false
permissions/install_location_provider=false
permissions/install_packages=false
permissions/install_shortcut=false
permissions/internal_system_window=false
permissions/internet=false
permissions/kill_background_processes=false
permissions/location_hardware=false
permissions/manage_accounts=false
permissions/manage_app_tokens=false
permissions/manage_documents=false
permissions/master_clear=false
permissions/media_content_control=false
permissions/modify_audio_settings=false
permissions/modify_phone_state=false
permissions/mount_format_filesystems=false
permissions/mount_unmount_filesystems=false
permissions/nfc=false
permissions/persistent_activity=false
permissions/process_outgoing_calls=false
permissions/read_calendar=false
permissions/read_call_log=false
permissions/read_contacts=false
permissions/read_external_storage=false
permissions/read_frame_buffer=false
permissions/read_history_bookmarks=false
permissions/read_input_state=false
permissions/read_logs=false
permissions/read_phone_state=false
permissions/read_profile=false
permissions/read_sms=false
permissions/read_social_stream=false
permissions/read_sync_settings=false
permissions/read_sync_stats=false
permissions/read_user_dictionary=false
permissions/reboot=false
permissions/receive_boot_completed=false
permissions/receive_mms=false
permissions/receive_sms=false
permissions/receive_wap_push=false
permissions/record_audio=false
permissions/reorder_tasks=false
permissions/restart_packages=false
permissions/send_respond_via_message=false
permissions/send_sms=false
permissions/set_activity_watcher=false
permissions/set_alarm=false
permissions/set_always_finish=false
permissions/set_animation_scale=false
permissions/set_debug_app=false
permissions/set_orientation=false
permissions/set_pointer_speed=false
permissions/set_preferred_applications=false
permissions/set_process_limit=false
permissions/set_time=false
permissions/set_time_zone=false
permissions/set_wallpaper=false
permissions/set_wallpaper_hints=false
permissions/signal_persistent_processes=false
permissions/status_bar=false
permissions/subscribed_feeds_read=false
permissions/subscribed_feeds_write=false
permissions/system_alert_window=false
permissions/transmit_ir=false
permissions/uninstall_shortcut=false
permissions/update_device_stats=false
permissions/use_credentials=false
permissions/use_sip=false
permissions/vibrate=false
permissions/wake_lock=false
permissions/write_apn_settings=false
permissions/write_calendar=false
permissions/write_call_log=false
permissions/write_contacts=false
permissions/write_external_storage=false
permissions/write_gservices=false
permissions/write_history_bookmarks=false
permissions/write_profile=false
permissions/write_secure_settings=false
permissions/write_settings=false
permissions/write_sms=false
permissions/write_social_stream=false
permissions/write_sync_settings=false
permissions/write_user_dictionary=false
screen/immersive_mode=true
screen/orientation=0
screen/support_large=true
screen/support_normal=true
screen/support_small=true
screen/support_xlarge=true
screen/use_32_bits_view=true
user_permissions/0=false
user_permissions/1=false
user_permissions/10=false
user_permissions/11=false
user_permissions/12=false
user_permissions/13=false
user_permissions/14=false
user_permissions/15=false
user_permissions/16=false
user_permissions/17=false
user_permissions/18=false
user_permissions/19=false
user_permissions/2=false
user_permissions/3=false
user_permissions/4=false
user_permissions/5=false
user_permissions/6=false
user_permissions/7=false
user_permissions/8=false
user_permissions/9=false
version/code=1
version/name="1.0"

View File

@@ -1,9 +1,10 @@
[gd_scene load_steps=9 format=3 uid="uid://d0lrpf3mmjdsx"]
[gd_scene load_steps=10 format=3 uid="uid://d0lrpf3mmjdsx"]
[ext_resource type="PackedScene" uid="uid://dohp772jyjxb7" path="res://stage/stage.tscn" id="1_ybvw5"]
[ext_resource type="PackedScene" uid="uid://dfxo2jwbj4aeh" path="res://coin/coin.tscn" id="2_chew2"]
[ext_resource type="PackedScene" uid="uid://o5q0hy6cg6nt" path="res://enemy/enemy.tscn" id="3_nhwvs"]
[ext_resource type="PackedScene" uid="uid://cc4idhykjp5f5" path="res://player/player.tscn" id="4_ray4s"]
[ext_resource type="PackedScene" uid="uid://dp5vo5wn16sxd" path="res://touch_screen_ui/touch_screen_ui.tscn" id="5_7jktm"]
[sub_resource type="PhysicsMaterial" id="1"]
friction = 0.0
@@ -264,3 +265,5 @@ physics_material_override = SubResource("4")
[node name="Player" parent="." instance=ExtResource("4_ray4s")]
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -9.49833, -3.84189, 3.9334)
[node name="TouchScreenUI" parent="." instance=ExtResource("5_7jktm")]

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/icon.webp-e94f9a68b0f625a567a797079e4d325f.ct
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/particle.webp-973931d37118dc68803b55353a07e7d
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -151,7 +151,7 @@ surface_material_override/0 = SubResource("StandardMaterial3D_aw6a5")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
callback_mode_process = 0
libraries = {
"": SubResource("AnimationLibrary_pyoek")
&"": SubResource("AnimationLibrary_pyoek")
}
autoplay = "life"
@@ -159,6 +159,7 @@ autoplay = "life"
cast_shadow = 0
amount = 16
lifetime = 0.4
visibility_aabb = AABB(-4, -4, -4, 8, 8, 8)
mesh = SubResource("SphereMesh_hnt4a")
spread = 0.0
gravity = Vector3(0, 0, 0)

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/osb_down.webp-9c1833813ef4174c85dd69f362177c6
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/osb_fire.webp-154e2653c82838a02f0bae91ac04156
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/osb_jump.webp-d288fb386413bd39611fb89cfad2120
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/osb_left.webp-2e7a675a7e14843285bf9372377266c
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/osb_right.webp-a6039f7d31991d4f425ea07894becb
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/osb_up.webp-e391cb650b6ccc198c31c0a125801d15.
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -71,7 +71,6 @@ func _physics_process(delta: float) -> void:
movement_direction = movement_direction.normalized()
var jump_attempt := Input.is_action_pressed(&"jump")
var shoot_attempt := Input.is_action_pressed(&"shoot")
if is_on_floor():
var sharp_turn := horizontal_speed > 0.1 and \
@@ -154,7 +153,7 @@ func _physics_process(delta: float) -> void:
shoot_blend *= 0.97
if (shoot_blend < 0):
shoot_blend = 0
var shoot_attempt := Input.is_action_pressed(&"shoot")
if shoot_attempt and not prev_shoot:
shoot_blend = SHOOT_TIME
var bullet := preload("res://player/bullet/bullet.tscn").instantiate() as Bullet

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,9 @@
[gd_scene load_steps=28 format=3 uid="uid://cc4idhykjp5f5"]
[gd_scene load_steps=24 format=3 uid="uid://cc4idhykjp5f5"]
[ext_resource type="Script" uid="uid://juqqcu31phas" path="res://player/player.gd" id="1"]
[ext_resource type="Script" uid="uid://c34yhkkhix7m7" path="res://player/follow_camera.gd" id="2"]
[ext_resource type="PackedScene" uid="uid://yd1e7ai2k5cr" path="res://player/player.glb" id="3_uccbe"]
[ext_resource type="Texture2D" uid="uid://kujhqacj3v72" path="res://player/controls/osb_up.webp" id="4_lmv6w"]
[ext_resource type="Texture2D" uid="uid://68sox6egj4j7" path="res://player/controls/osb_down.webp" id="5_4oxdy"]
[ext_resource type="Texture2D" uid="uid://r6qxvqi0unib" path="res://player/controls/osb_left.webp" id="6_k2dm4"]
[ext_resource type="AudioStream" uid="uid://cdx3i7hr2acow" path="res://player/sound_shoot.wav" id="7"]
[ext_resource type="Texture2D" uid="uid://bw76q621n8fie" path="res://player/controls/osb_right.webp" id="7_yth2f"]
[ext_resource type="AudioStream" uid="uid://bplqk77bffdxr" path="res://player/sound_jump.wav" id="8"]
[sub_resource type="CapsuleShape3D" id="1"]
@@ -246,42 +242,6 @@ parameters/state/current_position = 0.395526
parameters/state/current_delta = 0.030673
parameters/state/blend_amount = 0.0
[node name="Forward" type="TouchScreenButton" parent="."]
visible = false
position = Vector2(72, 301)
texture_normal = ExtResource("4_lmv6w")
texture_pressed = ExtResource("4_lmv6w")
passby_press = true
action = "move_forward"
visibility_mode = 1
[node name="Backward" type="TouchScreenButton" parent="."]
visible = false
position = Vector2(72, 365)
texture_normal = ExtResource("5_4oxdy")
texture_pressed = ExtResource("5_4oxdy")
passby_press = true
action = "move_backwards"
visibility_mode = 1
[node name="Left" type="TouchScreenButton" parent="."]
visible = false
position = Vector2(29, 332)
texture_normal = ExtResource("6_k2dm4")
texture_pressed = ExtResource("6_k2dm4")
passby_press = true
action = "move_left"
visibility_mode = 1
[node name="Right" type="TouchScreenButton" parent="."]
visible = false
position = Vector2(114, 332)
texture_normal = ExtResource("7_yth2f")
texture_pressed = ExtResource("7_yth2f")
passby_press = true
action = "move_right"
visibility_mode = 1
[node name="SoundShoot" type="AudioStreamPlayer" parent="."]
stream = SubResource("AudioStreamRandomizer_basvh")
@@ -289,7 +249,7 @@ stream = SubResource("AudioStreamRandomizer_basvh")
stream = SubResource("AudioStreamRandomizer_axa7i")
volume_db = -6.0
[node name="BlobShadow" type="Decal" parent="."]
[node name="BlobShadow" type="Decal" parent="." groups=["bad_performer"]]
size = Vector3(1.6, 12, 1.6)
texture_albedo = SubResource("GradientTexture2D_kvc1x")
albedo_mix = 0.8

View File

@@ -15,13 +15,17 @@ config/description="Platformer 3D demo using a CharacterBody3D.
It uses similar code to the 2D platformer, but implemented in 3D."
config/tags=PackedStringArray("3d", "demo", "gridmap", "official", "physics")
run/main_scene="res://game.tscn"
config/features=PackedStringArray("4.4")
config/features=PackedStringArray("4.5")
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/stretch/mode="canvas_items"
[input]
ui_accept={
@@ -126,7 +130,7 @@ jump={
shoot={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null)
@@ -142,15 +146,16 @@ reset_position={
[physics]
common/physics_ticks_per_second=120
3d/default_gravity=22.0
3d/physics_engine="Jolt Physics"
3d/default_gravity=22.0
common/physics_interpolation=true
[rendering]
renderer/rendering_method="mobile"
textures/vram_compression/import_s3tc_bptc=true
lights_and_shadows/directional_shadow/size=8192
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=3
lights_and_shadows/positional_shadow/soft_shadow_filter_quality=0
textures/default_filters/anisotropic_filtering_level=4
anti_aliasing/quality/msaa_3d=2
textures/decals/filter=1

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/ceiling.webp-6c8ec1a6977577fc1d8308a5cb512679
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/ceiling_corner.webp-ca7ec745639aecae126fd4a7c
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/ceiling_wall.webp-a2509388480a65851c94c9802b5
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/corner.webp-19d67f2c1aa9fc8d73bfbbf23048dfc7.
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -4,21 +4,24 @@ importer="texture"
type="CompressedTexture2D"
uid="uid://ckwv7e3lpmorb"
path.s3tc="res://.godot/imported/corner_fix.webp-bc947c0527b474b1e52d39a93f6cd55a.s3tc.ctex"
path.etc2="res://.godot/imported/corner_fix.webp-bc947c0527b474b1e52d39a93f6cd55a.etc2.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"imported_formats": ["s3tc_bptc", "etc2_astc"],
"vram_texture": true
}
[deps]
source_file="res://stage/meshes/previews/corner_fix.webp"
dest_files=["res://.godot/imported/corner_fix.webp-bc947c0527b474b1e52d39a93f6cd55a.s3tc.ctex"]
dest_files=["res://.godot/imported/corner_fix.webp-bc947c0527b474b1e52d39a93f6cd55a.s3tc.ctex", "res://.godot/imported/corner_fix.webp-bc947c0527b474b1e52d39a93f6cd55a.etc2.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -26,6 +29,10 @@ mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/corner_fixr.webp-f8a3b48c3de3657d3feae52cbd1b
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/corner_floor.webp-4f169e0657e8e863aa27176076b
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/floor.webp-b85a23af779738e25dcf19a98af0e9bf.c
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/floor_corner.webp-52ec61e351f511540f9bc7e071e
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/floor_edge.webp-2b1d311f588181594223ff2499e04
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/ramp.webp-c6b29b1b5a12f02e6af194daf6eaf17c.ct
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/tree_top.webp-a7f7890527f3bc4a073c376ff409d72
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/trunk.webp-92bcc2a7715bb8a3efda00c90b505c03.c
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/trunk_deco.webp-46f5c0f9715c8cdf44667c1aed396
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/trunk_floor.webp-05bdbcaca4470d947e24ffebe03d
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/wall.webp-ec4abcc927508e3e016ab06abcc66c65.ct
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/wall_floor.webp-ae54ecb1aedc8c55691df7d552153
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/wall_var.webp-b06245055c14de7214238d1177e7a8c
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/panorama.webp-c655559bb5045314b4c9859b18ccd41
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.85
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/tiles_albedo.webp-e271e20c366fd5067a562330f69
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=false
process/premult_alpha=true
process/normal_map_invert_y=false

View File

@@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/tiles_rough.webp-30ecea7165f8cf37654c5fb80d3a
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
@@ -25,6 +27,10 @@ mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false

View File

@@ -0,0 +1,6 @@
extends CanvasLayer
func _ready() -> void:
hide()
if DisplayServer.is_touchscreen_available():
show()

View File

@@ -0,0 +1 @@
uid://cxln2mnrvhqes

View File

@@ -0,0 +1,71 @@
[gd_scene load_steps=4 format=3 uid="uid://dp5vo5wn16sxd"]
[ext_resource type="Script" uid="uid://cxln2mnrvhqes" path="res://touch_screen_ui.gd" id="1_xag24"]
[ext_resource type="PackedScene" uid="uid://dmr0fcamx7t56" path="res://touch_screen_ui/virtual_joystick/virtual_joystick_scene.tscn" id="2_2ea5h"]
[sub_resource type="CanvasTexture" id="CanvasTexture_7o5bd"]
[node name="TouchScreenUI" type="CanvasLayer"]
script = ExtResource("1_xag24")
[node name="Virtual Joystick" parent="." instance=ExtResource("2_2ea5h")]
deadzone_size = 0.0
clampzone_size = 100.0
[node name="HBoxContainer" type="HBoxContainer" parent="."]
anchors_preset = 6
anchor_left = 1.0
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
offset_left = -256.0
offset_top = -64.0
offset_bottom = 64.0
grow_horizontal = 0
grow_vertical = 2
[node name="jump" type="Control" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Label" type="Label" parent="HBoxContainer/jump"]
z_index = 5
z_as_relative = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
text = "JUMP"
horizontal_alignment = 1
vertical_alignment = 1
[node name="jumpbtn" type="TouchScreenButton" parent="HBoxContainer/jump"]
self_modulate = Color(0, 0, 0, 1)
scale = Vector2(124, 124)
texture_normal = SubResource("CanvasTexture_7o5bd")
action = "jump"
[node name="shoot" type="Control" parent="HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="shoot" type="Label" parent="HBoxContainer/shoot"]
z_index = 5
z_as_relative = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
text = "SHOOT"
horizontal_alignment = 1
vertical_alignment = 1
[node name="shoot2" type="TouchScreenButton" parent="HBoxContainer/shoot"]
self_modulate = Color(0, 0, 0, 1)
scale = Vector2(124, 124)
texture_normal = SubResource("CanvasTexture_7o5bd")
action = "shoot"

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bm30au8mjfc2f"
path="res://.godot/imported/joystick_base_outline.png-10c48a1df0a5944963dc6b6e90d68588.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://touch_screen_ui/virtual_joystick/textures/joystick_base_outline.png"
dest_files=["res://.godot/imported/joystick_base_outline.png-10c48a1df0a5944963dc6b6e90d68588.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bkvmydfn5saxg"
path="res://.godot/imported/joystick_tip.png-d799851ebdcc0cd712b3442777319a7b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://touch_screen_ui/virtual_joystick/textures/joystick_tip.png"
dest_files=["res://.godot/imported/joystick_tip.png-d799851ebdcc0cd712b3442777319a7b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dt13r06u87fib"
path="res://.godot/imported/joystick_tip_arrows.png-a13bc06d4d9d1ae7f7a205fb6c21775b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://touch_screen_ui/virtual_joystick/textures/joystick_tip_arrows.png"
dest_files=["res://.godot/imported/joystick_tip_arrows.png-a13bc06d4d9d1ae7f7a205fb6c21775b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
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/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
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

View File

@@ -0,0 +1,175 @@
class_name VirtualJoystick
extends Control
## A simple virtual joystick for touchscreens, with useful options.
## Github: https://github.com/MarcoFazioRandom/Virtual-Joystick-Godot
# EXPORTED VARIABLES
## 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.
WHEN_TOUCHED, ## Visible only when touched.
}
## 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 := "move_left"
@export var action_right := "move_right"
@export var action_up := "move_forward"
@export var action_down := "move_back"
# 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():
hide()
if visibility_mode == Visibility_mode.WHEN_TOUCHED:
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)
if visibility_mode == Visibility_mode.WHEN_TOUCHED:
show()
_touch_index = event.index
_tip.modulate = pressed_color
_update_joystick(event.position)
get_viewport().set_input_as_handled()
elif event.index == _touch_index:
_reset()
if visibility_mode == Visibility_mode.WHEN_TOUCHED:
hide()
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
return vector.length_squared() <= base_radius.x * base_radius.x
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:
# Release actions.
if output.x >= 0 and Input.is_action_pressed(action_left):
Input.action_release(action_left)
if output.x <= 0 and Input.is_action_pressed(action_right):
Input.action_release(action_right)
if output.y >= 0 and Input.is_action_pressed(action_up):
Input.action_release(action_up)
if output.y <= 0 and Input.is_action_pressed(action_down):
Input.action_release(action_down)
# Press actions.
if output.x < 0:
Input.action_press(action_left, -output.x)
if output.x > 0:
Input.action_press(action_right, output.x)
if output.y < 0:
Input.action_press(action_up, -output.y)
if output.y > 0:
Input.action_press(action_down, output.y)
func _reset() -> void:
is_pressed = false
output = Vector2.ZERO
_touch_index = -1
_tip.modulate = _default_color
_base.position = _base_default_position
_tip.position = _tip_default_position
# Release actions.
if use_input_actions:
for action:String in [action_left, action_right, action_down, action_up]:
if Input.is_action_pressed(action):
Input.action_release(action)

View File

@@ -0,0 +1 @@
uid://dopdsey3c34s0

View File

@@ -0,0 +1,51 @@
[gd_scene load_steps=4 format=3 uid="uid://dmr0fcamx7t56"]
[ext_resource type="Script" uid="uid://dopdsey3c34s0" path="res://touch_screen_ui/virtual_joystick/virtual_joystick.gd" id="1_8x4dy"]
[ext_resource type="Texture2D" uid="uid://bm30au8mjfc2f" path="res://touch_screen_ui/virtual_joystick/textures/joystick_base_outline.png" id="2_jhjs2"]
[ext_resource type="Texture2D" uid="uid://dt13r06u87fib" path="res://touch_screen_ui/virtual_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