You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
38 lines
1.8 KiB
38 lines
1.8 KiB
@tool |
|
extends EditorPlugin |
|
|
|
func _handles(obj: Object) -> bool: |
|
return obj is Node |
|
|
|
func _forward_3d_gui_input(camera: Camera3D, event: InputEvent) -> int: |
|
var root := EditorInterface.get_edited_scene_root() as Node3D |
|
|
|
var viewport := root.get_viewport() |
|
# Don't know about any negative effect of changing these and leaving them like that. |
|
viewport.gui_disable_input = false # Re-enable input, required for `push_input` to work at all. |
|
viewport.handle_input_locally = true # Let sub-viewport handle its own input, makes `set_input_as_handled` work as expected? |
|
|
|
# This will propagate input events into the edited scene, |
|
# including regular, GUI, shortcut, unhandled key and unhandled. |
|
viewport.push_input(event) |
|
|
|
# Enabling `physics_object_picking` causes `is_input_handled()` to always |
|
# return true, and object picking isn't immediate anyway, so let's just |
|
# do it ourselves. This doesn't support touch input, though. |
|
if !viewport.is_input_handled() and event is InputEventMouse: |
|
# Ray is cast from the editor camera's view. |
|
var from := camera.project_ray_origin(event.position) |
|
var to := from + camera.project_ray_normal(event.position) * camera.far |
|
|
|
# Actual collision is done in the edited scene though. |
|
var space := root.get_world_3d().direct_space_state |
|
var query := PhysicsRayQueryParameters3D.create(from, to) |
|
|
|
var result := space.intersect_ray(query) |
|
# The collider object isn't necessarily a `CollisionObject3D`. |
|
var obj := result.get("collider") as CollisionObject3D |
|
if obj and obj.visible: |
|
obj._input_event(camera, event, result["position"], result["normal"], result["shape"]) |
|
|
|
# If any node calls `set_input_as_handled()`, the event is not passed on to other editor gizmos / plugins. |
|
return AfterGUIInput.AFTER_GUI_INPUT_STOP if viewport.is_input_handled() else AfterGUIInput.AFTER_GUI_INPUT_PASS
|
|
|