Merge pull request #75688 from mnemoli/pickone

Add setting for picking only top-most overlapping collision object
This commit is contained in:
Rémi Verschelde 2024-02-12 13:33:08 +01:00
commit 2b36dcf70a
No known key found for this signature in database
GPG key ID: C3336907360768E1
3 changed files with 22 additions and 0 deletions

View file

@ -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.

View file

@ -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;
}
}
}
}
@ -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;
@ -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);
@ -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");

View file

@ -256,6 +256,7 @@ private:
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;
@ -601,6 +602,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;