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:
- Right click on the blue AnimTree box and choose 'Add SkelControl Chain'.
- 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.
- Choose the Head bone and you will see a new green connector in the AnimTree labeled 'Head'.
- Right click on the background and create a new SkelControlLookAt.
- Connect the SkelControlLookAt the to Head connector.
- 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.
- 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:
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.
| 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.
| 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.
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.
| 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.
| 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 |
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.
| 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.