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:
- Maintain Original Rotation: Does not rotate object as it is being moved.
- 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.
- Maintain Rotation To User: Maintains the object's original rotation for Y/Z axis to the user.
- Gravity Aligned Maintain Rotation To User: Maintains object's original rotation to user, but makes the object vertical. Useful for bounding boxes.
- Face User: Ensures object always faces the user. Useful for slates/panels.
- Face Away From User: Ensures object always faces away from user. Useful for slates/panels that are configured backwards.
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.
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.