Skip to content

Commit

Permalink
Merge pull request #75688 from mnemoli/pickone
Browse files Browse the repository at this point in the history
Add setting for picking only top-most overlapping collision object
  • Loading branch information
akien-mga committed Feb 12, 2024
2 parents 4e990cd + a407219 commit 2b36dcf
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 0 deletions.
5 changes: 5 additions & 0 deletions doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,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.
</member>
<member name="physics_object_picking_first_only" type="bool" setter="set_physics_object_picking_first_only" getter="get_physics_object_picking_first_only" default="false">
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.
</member>
<member name="physics_object_picking_sort" type="bool" setter="set_physics_object_picking_sort" getter="get_physics_object_picking_sort" default="false">
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.
Expand Down
14 changes: 14 additions & 0 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,9 @@ void Viewport::_process_picking() {

if (send_event) {
co->_input_event_call(this, ev, res[i].shape);
if (physics_object_picking_first_only) {
break;
}
}
}
}
Expand Down Expand Up @@ -3466,6 +3469,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;
Expand Down Expand Up @@ -4616,6 +4627,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);
Expand Down Expand Up @@ -4774,6 +4787,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");
Expand Down
3 changes: 3 additions & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ class Viewport : public Node {

bool physics_object_picking = false;
bool physics_object_picking_sort = false;
bool physics_object_picking_first_only = false;
List<Ref<InputEvent>> physics_picking_events;
ObjectID physics_object_capture;
ObjectID physics_object_over;
Expand Down Expand Up @@ -601,6 +602,8 @@ class Viewport : public Node {
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;

Expand Down

0 comments on commit 2b36dcf

Please sign in to comment.