UDN
Search public documentation

UsingSkeletalControllers
Licensees can log in.

Red links require licensee log in.

Interested in the Unreal engine?
Check out the licensing page.

Questions about UDN itself?
Contact the UDN Staff

Using Skeletal Controllers

Document Summary: Guide to creating different types of bone controllers for a Skeletal Mesh.

Revision History: Created by James Golding Updated by Laurent Delayen.

Overview

SkelControls allow you to modify a bone or set of bones in a skeletal mesh programatically. They are set up in the same tool as your animation blending - the AnimTreeEditor. You cannot connect AnimNodes and SkelControls together - they are separate systems but displayed in the same workspace for convenience. Think of it as the Animation flowing into the root 'AnimTree' box, and then the SkelControls allowing you to modify each bone in some way after that.

Example

Say you want to add a controller to get the head of a character to look at a particular target:

  1. Right click on the blue AnimTree box and choose 'Add SkelControl Chain'.
  2. A combo will pop up letting you pick what bone you wish to control. Note that you can only have one control chain for each bone.
  3. Choose the Head bone and you will see a new green connector in the AnimTree labeled 'Head'.
  4. Right click on the background and create a new SkelControlLookAt.
  5. Connect the SkelControlLookAt the to Head connector.
  6. Select the SkelControlLookAt and you should see a small blue diamond at the origin with widget arrows attached. You can use the widget to move the diamond around - that is your look-at target.
  7. You may need to change the settings of the SkelControlLookAt such as the LookAtAxis to get the head to be correctly oriented.

Here is a example from an AnimTree:

control_node.jpg

The slider on the SkelControl indicates its 'strength'. If you drag it down to zero, you will see the head does whatever the animation does. If you drag it to full, it will remain locked on its target. The orange button uses the BlendInTime and BlendOutTime of the SkelControl to blend the control into and out of the fully active state.

SkelControl Types

We'll now take a quick look at some of the different types of SkelControls.

Common properties

Some parameters are commone to all SkelControls:

ControlName This is the name used by the programmer to find a particular SkelControl from code and modify it. If you do not name a control, it cannot be modified in the game.
BlendInTime When the control is told to become active, this is the time it takes to blend to full strength.
BlendOutTime Similar to BlendInTime, this is the time taken for the control to blend to zero strength.
bPropogateSetActive If true, when this SkelControl is made active, the next one in the chain will be made active as well. See `Chaining And Sharing' later in this doc for more on chaining controls.
BoneScale Allows you to apply scaling to the bone that this controller is working on. Note that the scaling is applied to this bone and all below it.

Most positions and rotations specified by SkelControls allow you to choose the 'space' (or 'reference frame') that it is defined in. Here is a brief explanation of the various options:

BCS_WorldSpace Specified as a location in the world.
BCS_ActorSpace Specified relative to the Actor origin.
BCS_ComponentSpace Specified relative to the SkeletalMeshComponent origin.
BCS_ParentBoneSpace Specified in the reference frame of the parent bone of the bone that we are controlling.
BCS_BoneSpace Specified relative to the bone we are controlling.
BCS_OtherBoneSpace Specified relative to some other bone in the hierarchy (there should be a ..BoneName option in the controller to let you set which bone).

SkelControlSingleBone

This is a simple control that modifies the rotation and/or translation of a single bone. This could be useful for rotating an antenna for example. Here are some of the key properties of the SkelControlSingleBone

bApplyTranslation Indicates if anything should be done to the translation. If false, all other translation settings will be ignored.
bAddTranslation If true, the specified translation is added to the result of the animation. If false, it will replace the animated translation.
BoneTranslation The translation to apply to the bone.
BoneTranslationSpace The space to apply the translation in - see BoneControlSpace above.
TranslationSpaceBoneName If BoneTranslationSpace is BCS_OtherBoneSpace, this is the name of the bone to use.
bApplyRotation As with bApplyTranslation, this must be true for any rotation changes to take affect.
bAddRotation If true, rotation is added to animation result. If false, existing rotation is replaced.
BoneRotation The actually rotation to apply to the bone.
BoneRotationSpace Reference frame to apply the bone rotation in.
RotationSpaceBoneName If BoneRotationSpace is BCS_OtherBoneSpace, this is the name of the bone to use.

SkelControlLookAt

This is a controller used for adjusting the rotation of a bone so that it points at a particular target. You could use this for example to make a characters head look at a specified target. In the screen shot below, the head is looking at the blue diamond. The green cone indicates the maximum range that the head is allowed to move.

control_lookat.jpg

TargetLocation The location in space that the bone should point at.
TargetLocationSpace The space that TargetLocation is defined in.
TargetSpaceBoneName If TargetLocationSpace is BCS_OtherBoneSpace, this is the name of the bone to use.
LookAtAxis The axis if the controlled bone that should point at the target.
bInvertLookAtAxis Tells the LookAtAxis to point away from the target instead of at it.
bDefineUpAxis If this is false, the control will find the minimum rotation required to point the LookAtAxis at the target. The `roll' around that axis will still be coming from the animation. If this is true, the vertical axis for the bone is defined as well, so the orientation of the bone is then completely defined by the controller.
UpAxis If bDefineUpAxis is true, this is the axis of the bone that should point up in world space.
bInvertUpAxis If the UpAxis should point down rather than up.
bEnableLimit If we should limit the maximum angle that the bone is allowed to rotate to track its target.
bShowLimit If we should draw the green limit cone in the 3D viewport when this control is selected.
MaxAngle The maximum angle away from the reference pose that this bone is allowed to be rotated. Specified in degrees.
DeadZoneAngle If the target is within the `dead zone' angle of the current rotation, no action will be taken. The bone will only be rotated if the target moves further out of the dead zone.

By setting TargetLocationSpace to BCS_OtherBoneSpace, you can for example make a character always look at his hand.

SkelControlSpline

The spline controller does not the modify the bone itself, but takes a chain of bones above that bone and fits them to a spline. In the example below, we are using a normal SkelControlSingleBone to move the end of the sausage up. Then the SkelControlSpline is set to modify the 4 bones above this - so creates a spline between the start and end of the sausage. Note that this control does not maintain bone lengths.

control_spline.jpg

SplineLength The number of bones to walk up the hierarchy and modify to fit to a spline.
SplineBoneAxis The axis of the bones to point along the spline.
bInvertSplineBoneAxis If the SplineBoneAxis should be flipped.
EndSplineTension Controls the curvature at the end of the spline (near the controlled bone).
StartSplineTension Controls the curvature at the beginning of the spline.
BoneRotMode Controls how the bones are rotated along the length of the spline. More info below

The BoneRotMode setting lets you control how the bones along the spline are rotated by this controller:

SCR_NoChange The rotation of the bones is not modified, they are just translated to sit on the spline.
SCR_AlongSpline The bones are rotated so their SplineBoneAxis points along the spline.
SCR_Interpolate The rotation of each successive bone is a blend between the rotation of the bones at either end of the chain.

This control using the SCR_Interpolate setting can be useful when controlling the rotation of a bone at the top of the back, to smooth the rotation along the rest of the bones in the spine.

SkelControlLimb

This control uses UnrealEngine3's Inverse Kinematic solver. It takes a target location in world space, and attempts to rotate the two bones above the controlled one to reach that target. If the target is not reachable, the bone will be placed as close as possible. As well as specifying the target location for the end of the limb, you also specify a target for the joint to bend towards - this is the pink diamond in the 3D viewport.

Note that the Limb controller does not work if you have roll-bones in the hierarchy of the arm (ie if the lower arm is a child of the upper arm roll bone). You should build your skeletons so that the arm is composed of 2 bones, and not 4 bones. The following picture explains the problem.

ArmSkelHierarchy.jpg

The bones on the left are typical in 3d packages but aren't as efficient for real time skeletal controls. In this arm chain if you wanted to turn this into ik, you would have an IK chain of 4 bones, when you can get away with only 2 bones like the bones that are one the right in the attached image. The roll bones are children of the arm bones in both situations. The difference is that the left is a straight hierarchy of 4 bones from the upper arm to the hand, while the right is a hierarchy of 2 bones from the upper arm to the hand.

control_limb.jpg

EffectorLocation The desired location of the controlled bone.
EffectorLocationSpace The space that EffectorLocation is defined in.
EffectorSpaceBoneName If EffectorLocationSpace is BCS_OtherBoneSpace, this is the name of the bone to use.
JointTargetLocation Location in space that the joint will move towards when flexed.
JointTargetLocationSpace The space that JointTargetLocation is defined in.
JointTargetSpaceBoneName If JointTargetLocationSpace is BCS_OtherBoneSpace, this is the name of the bone to use.
BoneAxis The axis of the bones in the limb that point `along' the bone.
JointAxis The axis of the bone that should be aligned with the joint axis. So for an elbow - this should be the axis around which the elbow bends.
bInvertBoneAxis Whether the BoneAxis vector should be inverted.
bInvertJointAxis Whether the JointAxis vector should be inverted.
bMaintainEffectorRelRot If true, modify the relative rotation between the end 'effector' bone and its parent bone. If false, the rotation of the end bone will not be modified by this controller.

SkelControlFootPlacement

This is a special type of SkelControlLimb that is designed to place the feet of a character properly on the ground. You should attach this control to the foot bone of your character. A line check is performed each frame from the position of the hip bone to the position of the foot bone. If nothing is hit, the leg is not changed. If something is hit, the EffectorLocation for the control is set to the hit point, so the leg will bend to place the foot on the ground. Because the EffectorLocation is generated automatically, you cannot modify it using the widget in the control, but you can modify the JointTargetLocation to get the legs to bend in the correct direction.

control_foot.jpg

FootOffset Offset applied to the generated EffectorLocation to pull it back along the line test. This allows you adjust the height of the foot on the ground, as the foot bone is not usually at the sole of the foot.
FootUpAxis The axis of the foot bone to align to the surface normal if bOrientFootToGround is true.
FootRotOffset Additional rotation applied to foot when bOrientFootToGround. This can be required if the foot bone does not have an axis that points up.
bInvertFootUpAxis If we should flip the FootUpAxis.
bOrientFootToGround If we should rotate the foot bone so that it aligns itself with the surface normal that was hit by the line check.
MaxUpAdjustment The maximum amount up the foot will be moved by the controller.
MaxDownAdjustment The maximum amount down the foot will be moved by the controller.

In the AnimTreeEditor you can display a preview floor mesh for testing foot placement. Press the `Show Floor' button on the toolbar and the floor mesh should appear. You can move and rotate the floor by holding the Control key and using the following controls:

Left Mouse Button Translate floor along X and Y
Right Mouse Button Rotate floor around Z
Left + Right Mouse Button Translate floor along Z

Mesh Offsetting

Animations are authored on a flat ground, so if the character is stepping on something higher than the ground, the foot placement code will raise the foot, and everything will look fine. Now if the collision happens below the animated ground level, for example going down stairs, then either the foot will remain in the air, or the leg will over extend to reach the step below. This is not something that we'd want. So typically the gameplay code would look at the smallest distance to the actual floor from both feet, and move the mesh with that offset, and a bit of interpolation to keep things smooth. You can find an example of such code in the Unreal Tournament 3 source code, AUTPawn::DoFootPlacement in UTPawn.cpp.

Advanced Foot Placement

The above solution, by doing just a trace to floor and controlling the leg bones directly is not very flexible and will only work when the character is standing still. There are some ways to improve this and make it more flexible.

Foot Placement while moving

One way to achieve foot placement while moving (and not just when standing still) is to take into account the offset (height) between the foot bone, and the animated ground level (which is usually represented by the Root Bone position). Now instead of moving our Foot Bone to where the ground actually is, we just add an offset to the Foot Bone, being the difference between the animated ground height and the actual ground height. Now the animation will properly lift the foot and follow the world. It will require a bit of interpolation, smoothing, and mesh offsetting love to look good, but it is a fairly simple solution to put in place and works fairly well. That system will also tend to lag a little bit as you are monitoring the ground level just below the feet. One way to improve this would be to look ahead where the foot would land, but that would require a more complex system in place which analyzes the locomotion animations to properly predict where the feet will land. Below are screenshots of the system prototyped using the Gears of War 2 code.

FootPlacementWhileMoving.jpg

Floor Conforming

Floor Conforming is orienting the character and/or his legs against the slope, so his feet move parallel to the slope. A simple way to achieve this is by having an IK Foot Bone Setup in the character's skeleton. Basically an "IK Foot Root" bone coming of the "Root Bone", and "IK Foot Right", "IK Foot Left" bones matching the foot bones exactly at every frame of animation. Then by translating and rotating the "IK Foot Root" bone, it is pretty easy to orient the feet movement against the direction of the slope. Again, some interpolation and mesh offsetting is required for it to look smooth. Additionally, the whole mesh can be rotated to adjust the torso of the character to the slope, and the change of slope, for it to look more natural. (Leaning a little into the slope when moving, and against the slope when stopping). Compensating for Mesh rotation in the aiming code is very easy to do, to keep the character aiming at a given point in space. Below are screenshots of the system prototyped using the Gears of War 2 code.

FloorConforming.jpg

Moving Bases

When a character is standing on top of a moving base, or otherwise known as a Mover, if that Mover happens to be rotating, the character will appear to be sliding and completely disconnected from the ground. Doing the Floor Conforming system discussed above will help, but still the character will slide against the base, the feet won't appear grounded at all. Why is that? This is because Unreal uses an AABB (Axis Aligned Bounding Box) for Pawn collision. So that box does not rotate with the Mover. And worse, it is pushed upwards and downwards as the Mover rotates. With a bit of maths though, it is possible to figure out where the feet lie and do the necessary compensations. You also have to ensure that the Mover is ticked before the Pawn. Below are screenshots of the system prototyped using the Gears of War 2 code.

FootPlacementMovers.jpg

SkelControlWheel

This is special controller designed to work with UE3's vehicle system. Vehicles use SkeletalMeshes with a bone for each wheel. Before the wheels will move and steer in the game you must create a SkelControlWheel for each one, give it a name, and then use that name to identify the control in the vehicle set-up. The vehicle system will then update the control each frame to make the wheel match the vertical movement, roll and steering of the underlying simulation.

control_wheel.jpg

WheelDisplacement This is just for previewing the vertical movement of the wheel. Setting this number should raise the wheel.
WheelMaxRenderDisplacement This is the maximum vertical distance that the wheel will be moved. This is used to ensure the wheel will never clip into chassis geometry.
WheelRoll Similar to WheelDisplacement, this is used to preview the wheel rolling. A positive value should make the wheel roll as if the car is moving forwards.
WheelRollAxis Which axis of the wheel bone the wheel should roll about.
WheelSteering Used to preview steering movement of the wheel. A positive number should move the wheel to point to the right.
WheelSteeringAxis The axis of the wheel bone that the wheel should rotate about to steer.
bInvertWheelRoll Invert rotation for the roll.
bInvertWheelSteering Invert rotation for the steering.

Chaining And Sharing

SkelControls can be chained together, and are applied in the order that they are connected. So if you apply a SkelControlLookAt, followed by a SkelControlSingleBone adding some rotation, first the bone will look at the target, and the be offset by that rotation.

SkelControl can also be shared by multiple bones. So if you want many bones to point at the same target, you can use just one SkelControlLookAt and connect multiple bones to it.