godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.13k stars 93 forks source link

Make input_ray_pickable CollisionObjects sensitive to collision layers #9135

Open BMagnu opened 7 months ago

BMagnu commented 7 months ago

Describe the project you are working on

A 3D game where a significant amount of objects regularly change whether or not they are pickable.

Describe the problem or limitation you are having in your project

Objects with input_ray_pickable=true will currently always trigger an input_event signal if at least one collision_layer bit is set. This makes quickly changing which objects trigger these signals cumbersome, as it requires either iterating through all objects and setting the input_ray_pickable property, or forcing the objects themselves to sort whether or not they should be pickable.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Instead, objects with input_ray_pickable=true should respect in which collision layer they are. Ideally, something like the current camera that performs the ray cast for triggering input events should have collision layer masks that determine which collision objects can or can't be picked, like pretty much all other types of collision object interactions (including manual raycasts).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Add a "Collision Mask" selector to the Camera nodes, similar to Raycast nodes. A collision of the camera raycast will only count if one bit of the collision mask matches an objects collision layer.

If this enhancement will not be used often, can it be worked around with a few lines of script?

It can be worked around by simply manually raycasting instead of using the input_event functionality. But I believe the enhancement to be worth it for two reasons:

  1. It saves time by allowing the already existing internal shortcut to be used for much more extensive and complex use cases without much change.
  2. It brings the input_event-style camera ray casts up to feature parity with manual ray casts with regards to collision layers

Is there a reason why this should be core and not an add-on in the asset library?

Since the input_event-style raycasts from the camera already exists, this is likely a very small change to core, whereas it'd require significant reimplementation for an add-on

Sauermann commented 7 months ago

I assume, this could be also a use-case for 2D. So an alternative to the suggested solution of adding a "Collision Mask" to the Camera would be to add this "Collision Mask" to the Viewport next to Viewport.physics_object_picking.

BMagnu commented 7 months ago

Could the Camera2D node not also recieve collision masks?

Cameras have the advantage of allowing a more verbose settings per camera not just per viewport, but as a downside also require this setting to be done per Camera instead of only once.

Sauermann commented 7 months ago

In 2D you don't need a Camera2D, while in 3D you need a Camera3D: It is possible to set the canvas_transorm directly without the need for a Camera2D. That is the reason for my alternative approach with the Viewport.

BMagnu commented 7 months ago

Mhm, fair. I think an ideal solution would use the viewport properties, and override them with camera properties if a camera is used to render the scene. That way, you can still have the verbosity of different settings per camera, while not requiring the use of a camera in 2D to use this feature.

mlaass commented 2 months ago

This is a useful feature. People currently work around this by switching off ray_pickable. In a game like an RTS where you you are picking and dragging a lot and have different modes, this is very useful. While this is a small feature with possibly a small audience, it is nevertheless a big quality of life improvement for the cases where this is needed.