Class GrabberScript
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
ForcePerKilogram
Force cap per kilogram of held body, so mass does not change how the drag feels.
public float ForcePerKilogram { get; set; }
Property Value
Held
The body being held, or null.
[DataMemberIgnore]
public BodyComponent? Held { get; }
Property Value
HoldDistance
Distance from the camera to the carry point while holding.
[DataMemberIgnore]
public float HoldDistance { get; }
Property Value
MaxDistance
How far from the camera a body can be picked up.
public float MaxDistance { get; set; }
Property Value
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
RotationSensitivity
Radians of body rotation per screen width of mouse travel while RotateKey is held.
public float RotationSensitivity { get; set; }
Property Value
SpringDampingRatio
Spring damping ratio of the hold. Above 1 there is no overshoot.
public float SpringDampingRatio { get; set; }
Property Value
SpringFrequency
Spring stiffness of the hold, in hertz. Higher snaps harder and starts to fight the solver.
public float SpringFrequency { get; set; }
Property Value
WheelDistanceStep
How far one mouse-wheel notch moves the carry point along the ray.
public float WheelDistanceStep { get; set; }
Property Value
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
bodyBodyComponenthitPointVector3distancefloat
Returns
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
Released
Raised when the held body is let go, for any reason.
public event Action<BodyComponent>? Released