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.
49 lines
2.0 KiB
49 lines
2.0 KiB
#if TOOLS |
|
[Tool] |
|
public partial class ReceiveInputInEditorPlugin |
|
: EditorPlugin |
|
{ |
|
public override bool _Handles(GodotObject obj) |
|
=> obj is Node; |
|
|
|
public override int _Forward3DGuiInput(Camera3D camera, InputEvent ev) |
|
{ |
|
var root = (Node3D)EditorInterface.Singleton.GetEditedSceneRoot(); |
|
|
|
var viewport = root.GetViewport(); |
|
// Don't know about any negative effect of changing these and leaving them like that. |
|
viewport.GuiDisableInput = false; // Re-enable input, required for `PushInput` to work at all. |
|
viewport.HandleInputLocally = true; // Let sub-viewport handle its own input, makes `SetInputAsHandled` work as expected? |
|
|
|
// This will propagate input events into the edited scene, |
|
// including regular, GUI, shortcut, unhandled key and unhandled. |
|
viewport.PushInput(ev); |
|
|
|
// Enabling `PhysicsObjectPicking` causes `IsInputHandled()` 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.IsInputHandled() && (ev is InputEventMouse { Position: var mouse })) { |
|
// Ray is cast from the editor camera's view. |
|
var from = camera.ProjectRayOrigin(mouse); |
|
var to = from + camera.ProjectRayNormal(mouse) * camera.Far; |
|
|
|
// Actual collision is done in the edited scene though. |
|
var space = root.GetWorld3D().DirectSpaceState; |
|
var query = PhysicsRayQueryParameters3D.Create(from, to); |
|
|
|
var result = space.IntersectRay(query); |
|
// The collider object isn't necessarily a `CollisionObject3D`. |
|
var collider = (GodotObject)result.GetValueOrDefault("collider"); |
|
if (collider is CollisionObject3D { Visible: true } obj) { |
|
var pos = (Vector3)result["position"]; |
|
var normal = (Vector3)result["normal"]; |
|
var shape = (int)result["shape"]; |
|
obj._InputEvent(camera, ev, pos, normal, shape); |
|
} |
|
} |
|
|
|
// If any node calls `SetInputAsHandled()`, the event is not passed on to other editor gizmos / plugins. |
|
return viewport.IsInputHandled() ? (int)AfterGuiInput.Stop : (int)AfterGuiInput.Pass; |
|
} |
|
} |
|
#endif
|
|
|