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.
50 lines
2.0 KiB
50 lines
2.0 KiB
2 months ago
|
#if TOOLS
|
||
|
[Tool]
|
||
|
public partial class ReceiveInputInEditorPlugin
|
||
|
: EditorPlugin
|
||
|
{
|
||
|
public override bool _Handles(GodotObject obj)
|
||
|
=> true;
|
||
|
|
||
|
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
|