Prepare Android controller and export support

This commit is contained in:
Alexander Sellite 2026-08-03 02:14:38 -04:00
parent c84f305c34
commit d24f2f50c0
9 changed files with 192 additions and 11 deletions

View file

@ -51,6 +51,65 @@ ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash\nexport DISPLAY=:0\nunzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"\n\"{temp_dir}/{exe_name}\" {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash\nkill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")\nrm -rf \"{temp_dir}\""
[preset.2]
name="Android"
platform="Android"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter="builds/*,playtest/*,scripts/*"
export_path="builds/android/NETfishing-debug.apk"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.2.options]
custom_template/debug=""
custom_template/release=""
gradle_build/use_gradle_build=false
gradle_build/export_format=0
gradle_build/min_sdk=""
gradle_build/target_sdk=""
architectures/armeabi-v7a=false
architectures/arm64-v8a=true
architectures/x86=false
architectures/x86_64=false
version/code=30600
version/name="0.3.6-prealpha"
package/unique_name="io.makearmy.netfishing"
package/name="NETfishing"
package/signed=true
package/app_category=0
package/retain_data_on_uninstall=false
package/exclude_from_recents=false
package/show_in_android_tv=false
package/show_in_app_library=true
package/show_as_launcher_app=true
launcher_icons/main_192x192="res://icon.svg"
graphics/opengl_debug=false
screen/immersive_mode=true
screen/edge_to_edge=false
screen/support_small=false
screen/support_normal=true
screen/support_large=true
screen/support_xlarge=true
user_data_backup/allow=false
gesture/swipe_to_dismiss=false
permissions/internet=true
permissions/access_network_state=true
permissions/custom_permissions=PackedStringArray()
texture_format/s3tc_bptc=false
texture_format/etc2_astc=true
[preset.1]
name="Linux Desktop"

View file

@ -922,7 +922,10 @@ func _on_peer_identity_observed(_peer_id: int, status: String) -> void:
func _input(event: InputEvent) -> void:
if (
not event.is_action_pressed("ui_cancel")
not (
event.is_action_pressed("ui_cancel")
or event.is_action_pressed("open_system_menu")
)
or (event is InputEventKey and event.echo)
):
return

View file

@ -373,18 +373,28 @@ func _unhandled_input(event: InputEvent) -> void:
get_viewport().set_input_as_handled()
return
if (
var mouse_zoom_in: bool = (
event is InputEventMouseButton
and event.shift_pressed
and event.is_action_pressed("camera_zoom_in")
):
_set_target_zoom(_target_zoom - zoom_step)
get_viewport().set_input_as_handled()
elif (
)
var controller_zoom_in: bool = (
event is InputEventJoypadButton
and event.is_action_pressed("camera_zoom_in")
)
var mouse_zoom_out: bool = (
event is InputEventMouseButton
and event.shift_pressed
and event.is_action_pressed("camera_zoom_out")
):
)
var controller_zoom_out: bool = (
event is InputEventJoypadButton
and event.is_action_pressed("camera_zoom_out")
)
if mouse_zoom_in or controller_zoom_in:
_set_target_zoom(_target_zoom - zoom_step)
get_viewport().set_input_as_handled()
elif mouse_zoom_out or controller_zoom_out:
_set_target_zoom(_target_zoom + zoom_step)
get_viewport().set_input_as_handled()

View file

@ -19,6 +19,11 @@ config/icon="res://icon.svg"
[display]
window/stretch/aspect="expand"
window/handheld/orientation=0
[input_devices]
pointing/emulate_mouse_from_touch=true
[gui]
@ -53,11 +58,13 @@ move_right={
sprint={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":16,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":7,"pressure":0.0,"pressed":false,"script":null)
]
}
jump={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":16,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
sneak={
@ -73,11 +80,13 @@ slow_walk={
interact={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":16,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
]
}
fish_primary={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":32,"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(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":5,"axis_value":1.0,"script":null)
]
}
camera_drag={
@ -88,11 +97,13 @@ camera_drag={
camera_zoom_in={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":32,"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":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":10,"pressure":0.0,"pressed":false,"script":null)
]
}
camera_zoom_out={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":32,"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":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":9,"pressure":0.0,"pressed":false,"script":null)
]
}
hotbar_1={
@ -140,14 +151,31 @@ hotbar_9={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":16,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":57,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
hotbar_previous={
"deadzone": 0.2,
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
]
}
hotbar_next={
"deadzone": 0.2,
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
]
}
open_backpack={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":16,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":4,"pressure":0.0,"pressed":false,"script":null)
]
}
open_system_menu={
"deadzone": 0.2,
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":6,"pressure":0.0,"pressed":false,"script":null)
]
}
open_emotes={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":16,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
]
}
open_tacklebox={

19
scripts/build_android_debug.sh Executable file
View file

@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
readonly OUTPUT_PATH="${PROJECT_ROOT}/builds/android/NETfishing-debug.apk"
readonly GODOT_BIN="${GODOT_BIN:-godot}"
mkdir -p -- "$(dirname -- "${OUTPUT_PATH}")"
"${GODOT_BIN}" \
--headless \
--path "${PROJECT_ROOT}" \
--export-debug "Android" \
"${OUTPUT_PATH}"
test -s "${OUTPUT_PATH}"
sha256sum "${OUTPUT_PATH}"

View file

@ -0,0 +1,53 @@
extends SceneTree
func _init() -> void:
assert(
ProjectSettings.get_setting("display/window/handheld/orientation", -1) == 0
)
assert(
ProjectSettings.get_setting(
"input_devices/pointing/emulate_mouse_from_touch", false
)
)
assert(_has_joypad_motion(&"move_forward", JOY_AXIS_LEFT_Y, -1.0))
assert(_has_joypad_motion(&"move_backward", JOY_AXIS_LEFT_Y, 1.0))
assert(_has_joypad_motion(&"move_left", JOY_AXIS_LEFT_X, -1.0))
assert(_has_joypad_motion(&"move_right", JOY_AXIS_LEFT_X, 1.0))
assert(_has_joypad_button(&"jump", JOY_BUTTON_A))
assert(_has_joypad_button(&"interact", JOY_BUTTON_X))
assert(_has_joypad_motion(&"fish_primary", JOY_AXIS_TRIGGER_RIGHT, 1.0))
assert(_has_joypad_button(&"sprint", JOY_BUTTON_LEFT_STICK))
assert(_has_joypad_button(&"camera_zoom_out", JOY_BUTTON_LEFT_SHOULDER))
assert(_has_joypad_button(&"camera_zoom_in", JOY_BUTTON_RIGHT_SHOULDER))
assert(_has_joypad_button(&"hotbar_previous", JOY_BUTTON_DPAD_LEFT))
assert(_has_joypad_button(&"hotbar_next", JOY_BUTTON_DPAD_RIGHT))
assert(_has_joypad_button(&"open_backpack", JOY_BUTTON_BACK))
assert(_has_joypad_button(&"open_system_menu", JOY_BUTTON_START))
assert(_has_joypad_button(&"open_emotes", JOY_BUTTON_DPAD_UP))
print("android readiness validation passed")
quit()
func _has_joypad_button(action: StringName, button_index: JoyButton) -> bool:
for event: InputEvent in InputMap.action_get_events(action):
var button_event: InputEventJoypadButton = event as InputEventJoypadButton
if button_event != null and button_event.button_index == button_index:
return true
return false
func _has_joypad_motion(
action: StringName,
axis: JoyAxis,
direction: float,
) -> bool:
for event: InputEvent in InputMap.action_get_events(action):
var motion_event: InputEventJoypadMotion = event as InputEventJoypadMotion
if (
motion_event != null
and motion_event.axis == axis
and is_equal_approx(motion_event.axis_value, direction)
):
return true
return false

View file

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

View file

@ -34,12 +34,12 @@ func _ready() -> void:
func handle_input(event: InputEvent, can_open: bool) -> bool:
if not event.is_action("open_emotes"):
return false
var key_event: InputEventKey = event as InputEventKey
if key_event == null or key_event.echo:
if key_event != null and key_event.echo:
return false
if key_event.physical_keycode != KEY_C:
return false
if key_event.pressed:
if event.is_pressed():
if _is_open or not can_open:
return _is_open
open_menu()

View file

@ -193,6 +193,14 @@ func _unhandled_input(event: InputEvent) -> void:
or not _fishing_spot.can_change_hotbar_selection()
):
return
if event.is_action_pressed("hotbar_previous"):
_hotbar.cycle_selection(-1)
get_viewport().set_input_as_handled()
return
if event.is_action_pressed("hotbar_next"):
_hotbar.cycle_selection(1)
get_viewport().set_input_as_handled()
return
if event is InputEventKey and event.pressed and not event.echo:
for index: int in range(PlayerHotbarType.SLOT_COUNT):
if event.is_action_pressed("hotbar_%d" % (index + 1)):