Table of Contents

Class GrabberScript

Namespace
Stride.CommunityToolkit.Bepu
Assembly
Stride.CommunityToolkit.Bepu.dll

Pick up any dynamic body with the mouse, carry it on the end of the camera ray, and let go - with whatever velocity it had, so a flick throws it. Put it on the camera entity.

[DataContract("GrabberScript")]
[Display("Grabber (pick up bodies with the mouse)", null)]
[ComponentCategory("Physics")]
public class GrabberScript : SyncScript, IIdentifiable, ICollectorHolder
Inheritance
GrabberScript
Implements
Inherited Members
Extension Methods

Examples

game.GetCameraEntity().Add(new GrabberScript());

Remarks

The body is never moved directly. A OneBodyLinearServoConstraintComponent pulls the grabbed point toward the cursor and a OneBodyAngularServoConstraintComponent holds the orientation, so the solver stays in charge: the held body still collides, still pushes other bodies, and cannot be forced through a wall. Teleporting a kinematic body each frame, the other common way to drag, does none of that: the body stops colliding while held and has no velocity when let go.

Tuning follows bepuphysics2's demo grabber: a soft spring (5 Hz, damping ratio 2), a force cap scaled by the body's mass so heavy and light bodies drag alike, no angular servo on a body whose rotation is locked, and the held body kept awake. The grab ends by itself if the body turns kinematic or leaves the scene.

Keys: Button to grab and hold; the mouse wheel moves the carry point along the ray; RotateKey plus mouse movement turns the held body. All configurable, and none of them clash with the toolkit's camera controllers, which look with the right button.

Properties

Button

The mouse button that grabs while held down. Left by default; the camera controllers look with the right one.

public MouseButton Button { get; set; }

Property Value

MouseButton

ForcePerKilogram

Force cap per kilogram of held body, so mass does not change how the drag feels.

public float ForcePerKilogram { get; set; }

Property Value

float

Held

The body being held, or null.

[DataMemberIgnore]
public BodyComponent? Held { get; }

Property Value

BodyComponent

HoldDistance

Distance from the camera to the carry point while holding.

[DataMemberIgnore]
public float HoldDistance { get; }

Property Value

float

MaxDistance

How far from the camera a body can be picked up.

public float MaxDistance { get; set; }

Property Value

float

RotateKey

Hold this key while grabbing to turn the held body with the mouse instead of moving it.

public Keys RotateKey { get; set; }

Property Value

Keys

RotationSensitivity

Radians of body rotation per screen width of mouse travel while RotateKey is held.

public float RotationSensitivity { get; set; }

Property Value

float

SpringDampingRatio

Spring damping ratio of the hold. Above 1 there is no overshoot.

public float SpringDampingRatio { get; set; }

Property Value

float

SpringFrequency

Spring stiffness of the hold, in hertz. Higher snaps harder and starts to fight the solver.

public float SpringFrequency { get; set; }

Property Value

float

WheelDistanceStep

How far one mouse-wheel notch moves the carry point along the ray.

public float WheelDistanceStep { get; set; }

Property Value

float

Methods

Cancel()

public override void Cancel()

Grab(BodyComponent, Vector3, float)

Grabs body at hitPoint, carried distance in front of the camera. The mouse path calls this from a raycast; a game can call it to hand the player something.

public bool Grab(BodyComponent body, Vector3 hitPoint, float distance)

Parameters

body BodyComponent
hitPoint Vector3
distance float

Returns

bool

false when the body cannot be held: kinematic, infinite mass, or already holding one.

Release()

Lets go of the held body, if any. It keeps its current velocity.

public void Release()

Start()

public override void Start()

Update()

public override void Update()

Events

Grabbed

Raised when a body is picked up.

public event Action<BodyComponent>? Grabbed

Event Type

Action<BodyComponent>

Released

Raised when the held body is let go, for any reason.

public event Action<BodyComponent>? Released

Event Type

Action<BodyComponent>