Skip to content

Commit bbe97af

Browse files
committed
Merge pull request godotengine#75688 from mnemoli/pickone
Add setting for picking only top-most overlapping collision object
2 parents 99a8438 + 0b0587a commit bbe97af

3 files changed

Lines changed: 22 additions & 0 deletions

File tree

doc/classes/Viewport.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@
307307
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
308308
[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.
309309
</member>
310+
<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">
311+
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].
312+
If [code]false[/code], an input_event signal will be sent to all physics objects in the mouse picking process.
313+
This applies to 2D CanvasItem object picking only.
314+
</member>
310315
<member name="physics_object_picking_sort" type="bool" setter="set_physics_object_picking_sort" getter="get_physics_object_picking_sort" default="false">
311316
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.
312317
[b]Note:[/b] This setting is disabled by default because of its potential expensive computational cost.

scene/main/viewport.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,9 @@ void Viewport::_process_picking() {
856856

857857
if (send_event) {
858858
co->_input_event_call(this, ev, res[i].shape);
859+
if (physics_object_picking_first_only) {
860+
break;
861+
}
859862
}
860863
}
861864
}
@@ -3466,6 +3469,14 @@ bool Viewport::get_physics_object_picking_sort() {
34663469
return physics_object_picking_sort;
34673470
}
34683471

3472+
void Viewport::set_physics_object_picking_first_only(bool p_enable) {
3473+
physics_object_picking_first_only = p_enable;
3474+
}
3475+
3476+
bool Viewport::get_physics_object_picking_first_only() {
3477+
return physics_object_picking_first_only;
3478+
}
3479+
34693480
Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const {
34703481
ERR_READ_THREAD_GUARD_V(Vector2());
34713482
Transform2D xf = stretch_transform * global_canvas_transform;
@@ -4616,6 +4627,8 @@ void Viewport::_bind_methods() {
46164627
ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
46174628
ClassDB::bind_method(D_METHOD("set_physics_object_picking_sort", "enable"), &Viewport::set_physics_object_picking_sort);
46184629
ClassDB::bind_method(D_METHOD("get_physics_object_picking_sort"), &Viewport::get_physics_object_picking_sort);
4630+
ClassDB::bind_method(D_METHOD("set_physics_object_picking_first_only", "enable"), &Viewport::set_physics_object_picking_first_only);
4631+
ClassDB::bind_method(D_METHOD("get_physics_object_picking_first_only"), &Viewport::get_physics_object_picking_first_only);
46194632

46204633
ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
46214634
ClassDB::bind_method(D_METHOD("push_text_input", "text"), &Viewport::push_text_input);
@@ -4774,6 +4787,7 @@ void Viewport::_bind_methods() {
47744787
ADD_GROUP("Physics", "physics_");
47754788
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking");
47764789
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_sort"), "set_physics_object_picking_sort", "get_physics_object_picking_sort");
4790+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking_first_only"), "set_physics_object_picking_first_only", "get_physics_object_picking_first_only");
47774791
ADD_GROUP("GUI", "gui_");
47784792
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled");
47794793
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled");

scene/main/viewport.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ class Viewport : public Node {
256256

257257
bool physics_object_picking = false;
258258
bool physics_object_picking_sort = false;
259+
bool physics_object_picking_first_only = false;
259260
List<Ref<InputEvent>> physics_picking_events;
260261
ObjectID physics_object_capture;
261262
ObjectID physics_object_over;
@@ -601,6 +602,8 @@ class Viewport : public Node {
601602
bool get_physics_object_picking();
602603
void set_physics_object_picking_sort(bool p_enable);
603604
bool get_physics_object_picking_sort();
605+
void set_physics_object_picking_first_only(bool p_enable);
606+
bool get_physics_object_picking_first_only();
604607

605608
Variant gui_get_drag_data() const;
606609

0 commit comments

Comments
 (0)