Manipulator components allow an actor to be picked up by a user and then moved, rotated or scaled.
The Generic Manipulator component is a general-purpose implementation of the Manipulator Component Base. It supports both one and two-handed manipulation with a number of configurable settings to change its behavior.
If one-handed manipulation is enabled the actor can be moved with just one hand. This mode supports movement and rotation, but not scaling of the actor.
The way hand rotation translates into actor rotation depends on the One Hand Rotation Mode:
- Rotate About Object Center: Only works for articulated hands/controllers. Rotate object using rotation of the hand/controller, but about the object center point. Useful for inspecting at a distance.
- Rotate About Grab Point: Only works for articulated hands/controllers. Rotate object as if it was being held by hand/controller. Useful for inspection.
If two-handed manipulation is enabled the actor can be moved, rotated, and scaled by grabbing it with both hands. Each of these actions can be enabled or disabled separately as needed, e.g. an actor can have rotation and scaling enabled while movement is disabled.
Movement uses the center point between both hands, so each hand contributes half of the translation.
Rotation is based on imaginary axis between both hands. The actor will rotate with the change of this axis, while avoiding roll around it.
Scaling uses the change in distance between hands.
Manipulation of an object can be constrained using transform constraints. Transform constraints are components that are added to an actor and are used by the manipulator to limit its effects on the target component. Constraints can be added to a blueprint or actor using the constraint picker, which is exposed in the Constraints dropdown on the generic manipulator. The constraint picker automatically populates with classes inheriting from
UxtTransformConstraint so user defined constraints can also be added using this dialog box.
The constraint manager can be configured to automatically detect and use all constraints attached to the actor or a user selected subset of the attached constraints.
The generic manipulator has a simple smoothing option to reduce jittering from noisy input. This becomes especially important with one-handed rotation, where hand tracking can be unreliable and the resulting transform amplifies jittering.
The smoothing method is based on a low-pass filter that gets applied to the source transform location and rotation. The resulting actor transform
T_final is a exponentially weighted average of the current transform
T_current and the raw target transform
T_target based on the time step:
T_final = Lerp( T_current, T_target, Exp(-Smoothing * DeltaSeconds) )
Manipulating a Procedural Mesh
When using the Generic Manipulator with a Procedural Mesh, you will need to:
- Disable "Use Complex as Simple Collision" on the Procedural Mesh.
- Set "Create Collision" when creating the Procedural Mesh.
This is due to UXTools only querying for simple collision volumes when detecting interaction targets, in order to ensure correct detection in all situations. You can read more about simple vs complex collisions here.
Manipulating physics-enabled components
Sometimes you want to manipulate components that are physics-enabled, that is, components affected by gravity and collisions with other actors. If your physically simulated component (e.g. a Static Mesh Component with Simulate Physics enabled) is the root component of the actor, Generic Manipulator will work out of the box. If the component is not the root, you'll have to set it as the target component of the manipulator:
This is necessary because:
- By default Generic Manipulator modifies the transform of the actor's root component.
- Physics-enabled components detach themselves from their attach parents automatically at simulation start.