summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/OS.xml8
-rw-r--r--editor/action_map_editor.cpp47
-rw-r--r--editor/action_map_editor.h2
-rw-r--r--editor/editor_settings.cpp16
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp27
5 files changed, 53 insertions, 47 deletions
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 305258c8c5..f5a57ca1e3 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -55,14 +55,18 @@
<return type="void" />
<argument index="0" name="msec" type="int" />
<description>
- Delay execution of the current thread by [code]msec[/code] milliseconds. [code]msec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_msec] will do nothing and will print an error message.
+ Delays execution of the current thread by [code]msec[/code] milliseconds. [code]msec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_msec] will do nothing and will print an error message.
+ [b]Note:[/b] [method delay_msec] is a [i]blocking[/i] way to delay code execution. To delay code execution in a non-blocking way, see [method SceneTree.create_timer]. Yielding with [method SceneTree.create_timer] will delay the execution of code placed below the [code]yield[/code] without affecting the rest of the project (or editor, for [EditorPlugin]s and [EditorScript]s).
+ [b]Note:[/b] When [method delay_msec] is called on the main thread, it will freeze the project and will prevent it from redrawing and registering input until the delay has passed. When using [method delay_msec] as part of an [EditorPlugin] or [EditorScript], it will freeze the editor but won't freeze the project if it is currently running (since the project is an independent child process).
</description>
</method>
<method name="delay_usec" qualifiers="const">
<return type="void" />
<argument index="0" name="usec" type="int" />
<description>
- Delay execution of the current thread by [code]usec[/code] microseconds. [code]usec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_usec] will do nothing and will print an error message.
+ Delays execution of the current thread by [code]usec[/code] microseconds. [code]usec[/code] must be greater than or equal to [code]0[/code]. Otherwise, [method delay_usec] will do nothing and will print an error message.
+ [b]Note:[/b] [method delay_usec] is a [i]blocking[/i] way to delay code execution. To delay code execution in a non-blocking way, see [method SceneTree.create_timer]. Yielding with [method SceneTree.create_timer] will delay the execution of code placed below the [code]yield[/code] without affecting the rest of the project (or editor, for [EditorPlugin]s and [EditorScript]s).
+ [b]Note:[/b] When [method delay_usec] is called on the main thread, it will freeze the project and will prevent it from redrawing and registering input until the delay has passed. When using [method delay_usec] as part of an [EditorPlugin] or [EditorScript], it will freeze the editor but won't freeze the project if it is currently running (since the project is an independent child process).
</description>
</method>
<method name="dump_memory_to_file">
diff --git a/editor/action_map_editor.cpp b/editor/action_map_editor.cpp
index 6789b5be00..38db48a4d4 100644
--- a/editor/action_map_editor.cpp
+++ b/editor/action_map_editor.cpp
@@ -120,8 +120,8 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) {
physical_key_checkbox->set_visible(show_phys_key);
additional_options_container->show();
- // Update selected item in input list for keys, joybuttons and joyaxis only (since the mouse cannot be "listened" for).
- if (k.is_valid() || joyb.is_valid() || joym.is_valid()) {
+ // Update selected item in input list.
+ if (k.is_valid() || joyb.is_valid() || joym.is_valid() || mb.is_valid()) {
TreeItem *category = input_list_tree->get_root()->get_first_child();
while (category) {
TreeItem *input_item = category->get_first_child();
@@ -134,13 +134,14 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) {
}
// If event type matches input types of this category.
- if ((k.is_valid() && input_type == INPUT_KEY) || (joyb.is_valid() && input_type == INPUT_JOY_BUTTON) || (joym.is_valid() && input_type == INPUT_JOY_MOTION)) {
+ if ((k.is_valid() && input_type == INPUT_KEY) || (joyb.is_valid() && input_type == INPUT_JOY_BUTTON) || (joym.is_valid() && input_type == INPUT_JOY_MOTION) || (mb.is_valid() && input_type == INPUT_MOUSE_BUTTON)) {
// Loop through all items of this category until one matches.
while (input_item) {
bool key_match = k.is_valid() && (Variant(k->get_keycode()) == input_item->get_meta("__keycode") || Variant(k->get_physical_keycode()) == input_item->get_meta("__keycode"));
bool joyb_match = joyb.is_valid() && Variant(joyb->get_button_index()) == input_item->get_meta("__index");
bool joym_match = joym.is_valid() && Variant(joym->get_axis()) == input_item->get_meta("__axis") && joym->get_axis_value() == (float)input_item->get_meta("__value");
- if (key_match || joyb_match || joym_match) {
+ bool mb_match = mb.is_valid() && Variant(mb->get_button_index()) == input_item->get_meta("__index");
+ if (key_match || joyb_match || joym_match || mb_match) {
category->set_collapsed(false);
input_item->select(0);
input_list_tree->ensure_cursor_is_visible();
@@ -165,7 +166,6 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) {
if (allowed_input_types & INPUT_KEY) {
strings.append(TTR("Key"));
}
- // We don't check for INPUT_MOUSE_BUTTON since it is ignored in the "Listen Window Input" method.
if (allowed_input_types & INPUT_JOY_BUTTON) {
strings.append(TTR("Joypad Button"));
@@ -173,7 +173,9 @@ void InputEventConfigurationDialog::_set_event(const Ref<InputEvent> &p_event) {
if (allowed_input_types & INPUT_JOY_MOTION) {
strings.append(TTR("Joypad Axis"));
}
-
+ if (allowed_input_types & INPUT_MOUSE_BUTTON) {
+ strings.append(TTR("Mouse Button in area below"));
+ }
if (strings.size() == 0) {
text = TTR("Input Event dialog has been misconfigured: No input types are allowed.");
event_as_text->set_text(text);
@@ -214,12 +216,21 @@ void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &
return;
}
- // Ignore mouse
- Ref<InputEventMouse> m = p_event;
- if (m.is_valid()) {
+ // Ignore mouse motion
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
return;
}
+ // Ignore mouse button if not in the detection rect
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid()) {
+ Rect2 r = mouse_detection_rect->get_rect();
+ if (!r.has_point(mouse_detection_rect->get_local_mouse_position() + r.get_position())) {
+ return;
+ }
+ }
+
// Check what the type is and if it is allowed.
Ref<InputEventKey> k = p_event;
Ref<InputEventJoypadButton> joyb = p_event;
@@ -227,6 +238,7 @@ void InputEventConfigurationDialog::_listen_window_input(const Ref<InputEvent> &
int type = k.is_valid() ? INPUT_KEY : joyb.is_valid() ? INPUT_JOY_BUTTON :
joym.is_valid() ? INPUT_JOY_MOTION :
+ mb.is_valid() ? INPUT_MOUSE_BUTTON :
0;
if (!(allowed_input_types & type)) {
@@ -537,6 +549,8 @@ void InputEventConfigurationDialog::_notification(int p_what) {
icon_cache.joypad_button = get_theme_icon(SNAME("JoyButton"), SNAME("EditorIcons"));
icon_cache.joypad_axis = get_theme_icon(SNAME("JoyAxis"), SNAME("EditorIcons"));
+ mouse_detection_rect->set_color(get_theme_color(SNAME("dark_color_2"), SNAME("Editor")));
+
_update_input_list();
} break;
default:
@@ -575,7 +589,7 @@ void InputEventConfigurationDialog::set_allowed_input_types(int p_type_masks) {
}
InputEventConfigurationDialog::InputEventConfigurationDialog() {
- allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION;
+ allowed_input_types = INPUT_KEY | INPUT_MOUSE_BUTTON | INPUT_JOY_BUTTON | INPUT_JOY_MOTION | INPUT_MOUSE_BUTTON;
set_title(TTR("Event Configuration"));
set_min_size(Size2i(550 * EDSCALE, 0)); // Min width
@@ -590,12 +604,17 @@ InputEventConfigurationDialog::InputEventConfigurationDialog() {
tab_container->connect("tab_selected", callable_mp(this, &InputEventConfigurationDialog::_tab_selected));
main_vbox->add_child(tab_container);
- CenterContainer *cc = memnew(CenterContainer);
- cc->set_name(TTR("Listen for Input"));
+ // Listen to input tab
+ VBoxContainer *vb = memnew(VBoxContainer);
+ vb->set_name(TTR("Listen for Input"));
event_as_text = memnew(Label);
event_as_text->set_align(Label::ALIGN_CENTER);
- cc->add_child(event_as_text);
- tab_container->add_child(cc);
+ vb->add_child(event_as_text);
+ // Mouse button detection rect (Mouse button event outside this ColorRect will be ignored)
+ mouse_detection_rect = memnew(ColorRect);
+ mouse_detection_rect->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ vb->add_child(mouse_detection_rect);
+ tab_container->add_child(vb);
// List of all input options to manually select from.
diff --git a/editor/action_map_editor.h b/editor/action_map_editor.h
index aff3e6e957..e55cab3510 100644
--- a/editor/action_map_editor.h
+++ b/editor/action_map_editor.h
@@ -32,6 +32,7 @@
#define ACTION_MAP_EDITOR_H
#include "editor/editor_data.h"
+#include <scene/gui/color_rect.h>
// Confirmation Dialog used when configuring an input event.
// Separate from ActionMapEditor for code cleanliness and separation of responsibilities.
@@ -60,6 +61,7 @@ private:
// Listening for input
Label *event_as_text;
+ ColorRect *mouse_detection_rect;
// List of All Key/Mouse/Joypad input options.
int allowed_input_types;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 1953270b08..a255847a56 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -592,18 +592,16 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("editors/3d/navigation/warped_mouse_panning", true);
// 3D: Navigation feel
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/orbit_sensitivity", 0.4, "0.0,2,0.01")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/orbit_inertia", 0.05, "0.0,1,0.01")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/translation_inertia", 0.15, "0.0,1,0.01")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/zoom_inertia", 0.075, "0.0,1,0.01")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/manipulation_orbit_inertia", 0.075, "0.0,1,0.01")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/manipulation_translation_inertia", 0.075, "0.0,1,0.01")
+ EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/orbit_sensitivity", 0.25, "0.01,2,0.001")
+ EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/orbit_inertia", 0.0, "0,1,0.001")
+ EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/translation_inertia", 0.05, "0,1,0.001")
+ EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/navigation_feel/zoom_inertia", 0.05, "0,1,0.001")
// 3D: Freelook
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "editors/3d/freelook/freelook_navigation_scheme", 0, "Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft)")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_sensitivity", 0.4, "0.0,2,0.01")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_inertia", 0.1, "0.0,1,0.01")
- EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_base_speed", 5.0, "0.0,10,0.01")
+ EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_sensitivity", 0.25, "0.01,2,0.001")
+ EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_inertia", 0.0, "0,1,0.001")
+ EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "editors/3d/freelook/freelook_base_speed", 5.0, "0,10,0.01")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "editors/3d/freelook/freelook_activation_modifier", 0, "None,Shift,Alt,Meta,Ctrl")
_initial_set("editors/3d/freelook/freelook_speed_zoom_link", false);
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index cf451dce91..49496426db 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -265,15 +265,13 @@ void Node3DEditorViewport::_update_camera(real_t p_interp_delta) {
if (is_freelook_active()) {
// Higher inertia should increase "lag" (lerp with factor between 0 and 1)
// Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
- real_t inertia = EDITOR_GET("editors/3d/freelook/freelook_inertia");
- inertia = MAX(0.001, inertia);
+ const real_t inertia = EDITOR_GET("editors/3d/freelook/freelook_inertia");
real_t factor = (1.0 / inertia) * p_interp_delta;
// We interpolate a different point here, because in freelook mode the focus point (cursor.pos) orbits around eye_pos
camera_cursor.eye_pos = old_camera_cursor.eye_pos.lerp(cursor.eye_pos, CLAMP(factor, 0, 1));
- real_t orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
- orbit_inertia = MAX(0.0001, orbit_inertia);
+ const real_t orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
@@ -289,24 +287,9 @@ void Node3DEditorViewport::_update_camera(real_t p_interp_delta) {
camera_cursor.pos = camera_cursor.eye_pos + forward * camera_cursor.distance;
} else {
- //when not being manipulated, move softly
- real_t free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
- real_t free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
- //when being manipulated, move more quickly
- real_t manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia");
- real_t manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia");
-
- real_t zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
-
- //determine if being manipulated
- bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4);
- manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT);
- manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT);
- manipulated |= Input::get_singleton()->is_key_pressed(KEY_CTRL);
-
- real_t orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
- real_t translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
- zoom_inertia = MAX(0.0001, zoom_inertia);
+ const real_t orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
+ const real_t translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
+ const real_t zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));