Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1);
GLOBAL_DEF("input_devices/pointing/android/override_volume_buttons", false);
GLOBAL_DEF_BASIC("input_devices/pointing/android/disable_scroll_deadzone", false);
GLOBAL_DEF_BASIC("input_devices/pointing/enable_virtual_controller", false);

// These properties will not show up in the dialog. If you want to exclude whole groups, use add_hidden_prefix().
GLOBAL_DEF_INTERNAL("application/config/features", PackedStringArray());
Expand Down
48 changes: 48 additions & 0 deletions core/input/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@
#include "core/config/project_settings.h"
#include "core/input/default_controller_mappings.h"
#include "core/input/input_map.h"
#include "core/object/callable_mp.h"
#include "core/object/class_db.h"
#include "core/os/os.h"
#include "scene/gui/virtual_controller.h"
#include "scene/main/canvas_layer.h"
#include "scene/main/scene_tree.h"
#include "scene/main/window.h"

#ifdef DEV_ENABLED
#include "core/os/thread.h"
Expand Down Expand Up @@ -161,6 +166,8 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms", "amplitude"), &Input::vibrate_handheld, DEFVAL(500), DEFVAL(-1.0));
ClassDB::bind_method(D_METHOD("set_ignore_joypad_on_unfocused_application", "enable"), &Input::set_ignore_joypad_on_unfocused_application);
ClassDB::bind_method(D_METHOD("is_ignoring_joypad_on_unfocused_application"), &Input::is_ignoring_joypad_on_unfocused_application);
ClassDB::bind_method(D_METHOD("set_virtual_controller_enabled", "enable"), &Input::set_virtual_controller_enabled);
ClassDB::bind_method(D_METHOD("is_virtual_controller_enabled"), &Input::is_virtual_controller_enabled);
ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity);
ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
Expand Down Expand Up @@ -210,6 +217,7 @@ void Input::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emulate_mouse_from_touch"), "set_emulate_mouse_from_touch", "is_emulating_mouse_from_touch");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emulate_touch_from_mouse"), "set_emulate_touch_from_mouse", "is_emulating_touch_from_mouse");
Comment thread
Kazox61 marked this conversation as resolved.
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_joypad_on_unfocused_application"), "set_ignore_joypad_on_unfocused_application", "is_ignoring_joypad_on_unfocused_application");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_controller_enabled"), "set_virtual_controller_enabled", "is_virtual_controller_enabled");

BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
Expand Down Expand Up @@ -383,6 +391,10 @@ bool Input::_should_ignore_joypad_events() const {
return ignore_joypad_on_unfocused_application && !application_focused && !embedder_focused;
}

void Input::_project_settings_changed() {
set_virtual_controller_enabled(ProjectSettings::get_singleton()->get("input_devices/pointing/enable_virtual_controller"));
}

static JoyAxis _combine_device(JoyAxis p_value, int p_device) {
return JoyAxis((int)p_value | (p_device << 20));
}
Expand Down Expand Up @@ -1332,6 +1344,40 @@ bool Input::is_ignoring_joypad_on_unfocused_application() const {
return ignore_joypad_on_unfocused_application;
}

void Input::set_virtual_controller_enabled(bool p_enabled) {
virtual_controller_enabled = p_enabled;

if (Engine::get_singleton()->is_editor_hint()) {
return;
}

if (!virtual_controller_enabled && virtual_controller != nullptr) {
virtual_controller->queue_free();
virtual_controller = nullptr;
if (virtual_controller_canvas_layer != nullptr) {
virtual_controller_canvas_layer->queue_free();
virtual_controller_canvas_layer = nullptr;
}
}

if (virtual_controller_enabled && virtual_controller == nullptr) {
if (virtual_controller_canvas_layer == nullptr) {
virtual_controller_canvas_layer = memnew(CanvasLayer);
SceneTree::get_singleton()->get_root()->add_child(virtual_controller_canvas_layer, false, Node::INTERNAL_MODE_BACK);
virtual_controller_canvas_layer->set_name("_VirtualControllerCanvasLayer");
virtual_controller_canvas_layer->set_layer(128); // Ensure the virtual controller is on top of everything else.
}

virtual_controller = memnew(VirtualController);
virtual_controller_canvas_layer->add_child(virtual_controller, false, Node::INTERNAL_MODE_BACK);
virtual_controller->set_name("_VirtualController");
}
}

bool Input::is_virtual_controller_enabled() const {
return virtual_controller_enabled;
}

void Input::set_gravity(const Vector3 &p_gravity) {
_THREAD_SAFE_METHOD_

Expand Down Expand Up @@ -2372,6 +2418,8 @@ Input::Input() {
gyroscope_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_gyroscope", false);
magnetometer_enabled = GLOBAL_DEF_RST_BASIC("input_devices/sensors/enable_magnetometer", false);
ignore_joypad_on_unfocused_application = GLOBAL_DEF_RST_BASIC("input_devices/joypads/ignore_joypad_on_unfocused_application", false);

ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Input::_project_settings_changed));
}

Input::~Input() {
Expand Down
8 changes: 8 additions & 0 deletions core/input/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
#include "core/templates/rb_set.h"
#include "core/variant/typed_array.h"

class CanvasLayer;
class GamepadMotion;
class VirtualController;

namespace InputClassEnums {
// Keep synced with DisplayServerEnums::MouseMode enum.
Expand Down Expand Up @@ -129,6 +131,9 @@ class Input : public Object {
bool ignore_joypad_on_unfocused_application = false;
bool application_focused = true;
bool embedder_focused = false;
bool virtual_controller_enabled = false;
CanvasLayer *virtual_controller_canvas_layer = nullptr;
VirtualController *virtual_controller = nullptr;

struct ActionState {
uint64_t pressed_physics_frame = UINT64_MAX;
Expand Down Expand Up @@ -328,6 +333,7 @@ class Input : public Object {
EventDispatchFunc event_dispatch_function = nullptr;

bool _should_ignore_joypad_events() const;
void _project_settings_changed();

#ifndef DISABLE_DEPRECATED
void _vibrate_handheld_bind_compat_91143(int p_duration_ms = 500);
Expand Down Expand Up @@ -434,6 +440,8 @@ class Input : public Object {

void set_ignore_joypad_on_unfocused_application(bool p_ignore);
bool is_ignoring_joypad_on_unfocused_application() const;
void set_virtual_controller_enabled(bool p_enable);
bool is_virtual_controller_enabled() const;

void set_mouse_position(const Point2 &p_posf);

Expand Down
3 changes: 3 additions & 0 deletions doc/classes/Input.xml
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,9 @@
Input accumulation can be disabled to get slightly more precise/reactive input at the cost of increased CPU usage. In applications where drawing freehand lines is required, input accumulation should generally be disabled while the user is drawing the line to get results that closely follow the actual input.
[b]Note:[/b] Input accumulation is [i]enabled[/i] by default.
</member>
<member name="virtual_controller_enabled" type="bool" setter="set_virtual_controller_enabled" getter="is_virtual_controller_enabled">
If [code]true[/code], a virtual controller is created which sends controller input events based on touch input.
</member>
</members>
<signals>
<signal name="joy_connection_changed">
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1698,6 +1698,9 @@
<member name="input_devices/pointing/emulate_touch_from_mouse" type="bool" setter="" getter="" default="false">
If [code]true[/code], sends touch input events when clicking or dragging the mouse.
</member>
<member name="input_devices/pointing/enable_virtual_controller" type="bool" setter="" getter="" default="false">
If [code]true[/code], a virtual controller is created which sends controller input events based on touch input.
</member>
<member name="input_devices/sensors/enable_accelerometer" type="bool" setter="" getter="" default="false">
If [code]true[/code], the accelerometer sensor is enabled and [method Input.get_accelerometer] returns valid data.
</member>
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/VirtualController.xml
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be filled in in more detail

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VirtualController" inherits="Control" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A virtual controller for touchscreen devices.
</brief_description>
<description>
</description>
<tutorials>
</tutorials>
<theme_items>
<theme_item name="button" data_type="style" type="StyleBox">
The style of the virtual controller buttons.
</theme_item>
</theme_items>
</class>
6 changes: 6 additions & 0 deletions doc/classes/VirtualJoystick.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
Emitted when the tip moved outside the deadzone and the joystick is released. The [param input_vector] contains the last input direction and strength before release. Its length is between [code]0.0[/code] and [code]1.0[/code].
</description>
</signal>
<signal name="motion">
<param index="0" name="input_vector" type="Vector2" />
<description>
Emitted when the joystick is moved. The [param input_vector] contains the current input direction and strength. Its length is between [code]0.0[/code] and [code]1.0[/code].
</description>
</signal>
<signal name="pressed">
<description>
Emitted when the joystick is pressed.
Expand Down
1 change: 1 addition & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4510,6 +4510,7 @@ int Main::start() {
for (Node *E : to_add) {
sml->get_root()->add_child(E);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, please restore

OS::get_singleton()->benchmark_end_measure("Startup", "Load Autoloads");
}
}
Expand Down
Loading
Loading