From a4072196938ece22094be9f2e4b1d1fe19586be3 Mon Sep 17 00:00:00 2001 From: mnemoli Date: Tue, 4 Apr 2023 18:04:49 +0100 Subject: [PATCH] Add Viewport setting for picking only first-encountered CanvasItem physics object --- doc/classes/Viewport.xml | 5 +++++ scene/main/viewport.cpp | 14 ++++++++++++++ scene/main/viewport.h | 3 +++ 3 files changed, 22 insertions(+) diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 413d9462fec..e842c58769e 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -300,6 +300,11 @@ If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process. [b]Note:[/b] The number of simultaneously pickable objects is limited to 64 and they are selected in a non-deterministic order, which can be different in each picking process. + + If [code]true[/code], the input_event signal will only be sent to one physics object in the mouse picking process. If you want to get the top object only, you must also enable [member physics_object_picking_sort]. + If [code]false[/code], an input_event signal will be sent to all physics objects in the mouse picking process. + This applies to 2D CanvasItem object picking only. + If [code]true[/code], objects receive mouse picking events sorted primarily by their [member CanvasItem.z_index] and secondarily by their position in the scene tree. If [code]false[/code], the order is undetermined. [b]Note:[/b] This setting is disabled by default because of its potential expensive computational cost. diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index ad11c80c42d..b44f25409d7 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -846,6 +846,9 @@ void Viewport::_process_picking() { if (send_event) { co->_input_event_call(this, ev, res[i].shape); + if (physics_object_picking_first_only) { + break; + } } } } @@ -3280,6 +3283,14 @@ bool Viewport::get_physics_object_picking_sort() { return physics_object_picking_sort; } +void Viewport::set_physics_object_picking_first_only(bool p_enable) { + physics_object_picking_first_only = p_enable; +} + +bool Viewport::get_physics_object_picking_first_only() { + return physics_object_picking_first_only; +} + Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const { ERR_READ_THREAD_GUARD_V(Vector2()); Transform2D xf = stretch_transform * global_canvas_transform; @@ -4366,6 +4377,8 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking); ClassDB::bind_method(D_METHOD("set_physics_object_picking_sort", "enable"), &Viewport::set_physics_object_picking_sort); ClassDB::bind_method(D_METHOD("get_physics_object_picking_sort"), &Viewport::get_physics_object_picking_sort); + ClassDB::bind_method(D_METHOD("set_physics_object_picking_first_only", "enable"), &Viewport::set_physics_object_picking_first_only); + ClassDB::bind_method(D_METHOD("get_physics_object_picking_first_only"), &Viewport::get_physics_object_picking_first_only); ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid); ClassDB::bind_method(D_METHOD("push_text_input", "text"), &Viewport::push_text_input); @@ -4524,6 +4537,7 @@ void Viewport::_bind_methods() { ADD_GROUP("Physics", "physics_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_sort"), "set_physics_object_picking_sort", "get_physics_object_picking_sort"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_first_only"), "set_physics_object_picking_first_only", "get_physics_object_picking_first_only"); ADD_GROUP("GUI", "gui_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 68084fc35f2..3fda50ac43f 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -254,6 +254,7 @@ private: bool physics_object_picking = false; bool physics_object_picking_sort = false; + bool physics_object_picking_first_only = false; List> physics_picking_events; ObjectID physics_object_capture; ObjectID physics_object_over; @@ -595,6 +596,8 @@ public: bool get_physics_object_picking(); void set_physics_object_picking_sort(bool p_enable); bool get_physics_object_picking_sort(); + void set_physics_object_picking_first_only(bool p_enable); + bool get_physics_object_picking_first_only(); Variant gui_get_drag_data() const;