A game where you get to play as a slime, made with Godot.
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

#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