rj-action-library/Runtime/Interactions/Grabber.cs

125 lines
2.6 KiB
C#
Raw Normal View History

2025-01-21 20:58:56 +00:00
using Godot;
using System.Collections;
using System.Collections.Generic;
using Godot.Collections;
namespace Rokojori
{
[GlobalClass,Icon("res://addons/rokojori_action_library/Icons/Grabber.svg")]
public partial class Grabber:Node3D, SensorInputHandler
{
[Export]
public Sensor button;
[Export]
public Pointer pointer;
2025-05-27 06:51:48 +00:00
[Export]
public Action onGrab;
[Export]
public Action onRelease;
2025-01-21 20:58:56 +00:00
[Export]
public TimeLine timeLine;
[Export]
public Node3D grabOffset;
2025-05-21 20:44:28 +00:00
[Export]
public Smoothing positionSmoothing;
[Export]
public Smoothing rotationSmoothing;
2025-01-21 20:58:56 +00:00
[ExportGroup("Read Only")]
[Export]
public Grabbable grabbable;
2025-05-21 20:44:28 +00:00
2025-01-21 20:58:56 +00:00
public override void _Ready()
{
SensorManager.Register( this, button );
}
public override void _ExitTree()
{
SensorManager.Unregister( this, button );
}
TimeLineCallback _callback = null;
public void _OnSensor( SensorEvent se )
{
if ( se.isDown && _callback == null )
{
StartGrabbing();
}
else if ( se.isUp && _callback != null )
{
ReleaseGrabbing();
}
}
void StartGrabbing()
{
var pointable = pointer.pointable;
if ( pointable == null )
{
return;
}
2025-05-21 20:44:28 +00:00
grabbable = Nodes.Find<Grabbable>( pointable.GetParent() );
2025-01-21 20:58:56 +00:00
if ( grabbable == null )
{
return;
}
grabbable.SetGrabber( this );
_callback = TimeLineManager.ScheduleCallback( timeLine,
( cb )=>
{
if ( cb != _callback )
{
return;
}
2025-05-21 20:44:28 +00:00
positionSmoothing.SetCurrent( grabbable.grabTarget.GlobalPosition );
rotationSmoothing.SetCurrent( grabbable.grabTarget.GetGlobalQuaternion() );
2025-01-21 20:58:56 +00:00
UpdateGrabbable();
}
);
2025-05-27 06:51:48 +00:00
Action.Trigger( onGrab );
2025-01-21 20:58:56 +00:00
}
void ReleaseGrabbing()
{
2025-05-27 06:51:48 +00:00
if ( grabbable != null )
{
grabbable.SetGrabber( null );
grabbable = null;
}
2025-01-21 20:58:56 +00:00
_callback.done = true;
_callback = null;
2025-05-27 06:51:48 +00:00
Action.Trigger( onRelease );
2025-01-21 20:58:56 +00:00
}
2025-05-21 20:44:28 +00:00
void UpdateGrabbable()
2025-01-21 20:58:56 +00:00
{
2025-05-21 20:44:28 +00:00
// this.LogInfo( "Grabbing", HierarchyName.Of( grabbable ) );
grabbable.grabTarget.GlobalPosition = Smoothing.Apply( positionSmoothing, grabOffset.GlobalPosition, timeLine.delta );
grabbable.grabTarget.SetGlobalQuaternion( Smoothing.Apply( rotationSmoothing, grabOffset.GetGlobalQuaternion(), timeLine.delta ) );
2025-05-27 06:51:48 +00:00
grabbable.rigidBody3D.LinearVelocity = Vector3.Zero;
grabbable.rigidBody3D.AngularVelocity = Vector3.Zero;
2025-01-21 20:58:56 +00:00
}
}
}