UT Skeletal Animation Notes


PLEASE NOTE: this document is obsolete. Please consult the Unreal Developer Network site for the latest documentation including detailed tutorials and plugins.




The skeletal animation support in UT was designed to be almost completely backwards compatible with the vertex animation. This document assumes the artists/programmers are somewhat familiar with the process of creating/managing (vertex-) animation content for Unreal/Unreal Tournament (see "Animation Basics" )The animating vertices are replaced by an invisible hierarchy of animating bones, which move vertices of the mesh either directly or in weighted combinations. Content is created in 3D Studio Max 2.5/3.0/3.1 and exported to a custom (loss-less) binary format, and the animation data is digested (compressed) at package-building time.

During content rebuilds ('ucc make'), .PSA files are digested into UAnimation objects, and .PSK files into USkeletalMesh objects. The animations then work with the exact same commands and sequence-notification pathways as the classic vertex animated models.

Model files have the .PSK extension, animation files have a .PSA extension.  A path name needs to be set at all times, since that also determines the destination of the log files.

A .PSK (model) file can be saved at any time when your model is loaded. The .PSA (animation) file can consist of multiple animations which are 'digested', selected animations can then be grouped together, renamed, and saved/loaded.

Animations are 'bundled' into memory as they are digested by the exporter. The actual saving out to a file is done from a separate animation manager window (see its button) which allows
saving, loading and parameter tweaking of animations in previous bundled .PSA files. Changing parameters like the animation names, grouping names, and frame rates is done on the selected animation in the first list, which can then be shuffled back and forth to the second list which represents the .PSA file to be written. 

The Maya and Max exporters share the same user interfaces, but are activated differently.

Exporting Animations from 3D Studio Max

The exporter, ActorX is a utility plugin which you install by copying ActorX.dlu into your Max plugins folder. It can be activated in the utility pane (hammer tab-> more -> ActorX). ActorX will look for any hierarchy which has either Physique meshes or other meshes attached to it, and export either the skin + reference skeleton ('model') or the animation, using the filenames given in the main exporter utility pane. 

ExampleMax contains source art for two animated meshes - Piston.max and Player.max.
The script files used to link up content into a native Unreal package are Thing.uc and Warboss.uc.
The exporter was then used to create the intermediate .PSK (skin, mesh and reference skeleton) and .PSA (animation) files. The .pcx skins are 8-bit pallettized (and where desired, downsampled) versions of the original 24-bit image files used for the Max materials.
The ready-made native Unreal package containing the meshes, animations and textures is " Test.u ".  Placing this in the UnrealTournament\System folder along with the standard .u files allows the engine to access the data during game runtime. If your scene contains any meshes which need to be exported as part of a hierarchy while they're not explicitly physique-linked as a skin to bones or other objects, make sure the 'all textured geometry' option in the second pane is checked.
For all meshes linked with physique, it is extremely important to initialize and set them up from the very start exactly as outlined here; otherwise there is no guarantee that results in the engine will match what you're seeing in Max.

Exporting Animations from Maya

The different windows can be called up with specific Maya/Mel commands (easily bound to custom keys by dragging the marked command text to the toolbar) :

axmain       the main exporter panel
axoptions   brings up the second options/script export panel
axanim       starts the animation manager, which can save and load the platform-independent  .psa  animation files from disk, to edit the individual UT animation properties.
axbrush     non-skeletal .T3D textured architecture export.

ExampleMaya.zip contains example source art in Maya 3.0 format: two simple animated meshes, Piston.mb and Worm.mb.
The script files used to link up content into a native Unreal package are Piston.uc and Worm.uc.
The exporter was used to create the intermediate .PSK (skin, mesh and reference skeleton) and .PSA (animation) files.
The .pcx skins are 8-bit pallettized (and, where desired, downsampled) versions of the original 24-bit image files as used for the Maya materials. The ready-made native Unreal package containing the meshes, animations and textures is "Test.u".  Placing this in the UnrealTournament\System folder along with the standard .u files allows the engine to access the data during game runtime. 
Note that in Maya, there need to be actual 'Joint' objects for the exporter to recognize as a hierarchy, in contrast to the Max exporter, where any parenting of objects will do.

Exporter Options (second pane)

  • Skin selection checks ( effective for MAX exporter only )
    • All physique meshes - by default, export only mesh geometry consisting of Character Studio's Physique modifiers.
    • All textured geometry - export any textured meshes, which may be linked up by bones, or any parent/child bonds. The exporter treats these bonds like regular bones. This may also be needed when not all meshes linked to your skeleton are Physique'd.
  • Dummy culling - Checking this option makes the exporter disregard any dummy boxes which are at the ends of the hierarchy and have no effective links to any of the skin/geometry. Depending on the linkup, dummy culling can cause problems like erratic vertices and/or bones. It works OK though if you apply it after saving the skin, i.e. to the animation only.
  • Root motion lock - Check this to subtract the net root motion from an animation. 'Hard lock' will simply freeze the root node at it's frame-0 start position throughout the animation.

Engine Console Commands

These are in-game console commands that can be used to debug your meshes and animations.

  • stat anim - detailed real-time report on all animation (skeletal or regular) for meshes visible on the screen.
  • rend bone - toggles drawing of the bones when in wireframe mode.
  • rend blend - visualize the vertex-influence blending.  Green vertices have single links, red ones have two, pink three, light blue four, white have five or more.
  • rend wire - enables wireframe mode in normal (lit) render modes, but is currently disabled (cheating possibilities!) so RMODE 1 is the proper way to enter wireframe mode.

General Script Commands

Animation objects are linked up with actors at runtime. Any bone names that the actor's USkeletalMesh model has in common with the linked-up animation will be animated.

Skeletal meshes are imported with the MESH MODELIMPORT command, eg:


.PSK files as generated by the Max exporter are 'Reference skin-and-skeleton' raw data chunks,
which are converted to USkeletalMeshes which define a skin, materials and UV's, bone influences, and the named bones in a reference pose.

Animation files are imported with the ANIM IMPORT command:


UAnimation objects contain named bones, (compressed), any predefined sequences,  and movement tracks for each bone.

MaxKeys will put an adjustable squeeze on the number of keys in the animation as a whole; 
COMPRESS= does the same but with a simple factor ranging from 0 to 1.
Keys which can be interpolated most effectively are thrown out first, until we're left with the suggested number of keys (or lower, because 'perfectly' interpolatable keys are always thrown out, and all static tracks are collapsed into 1-key tracks). The initial, non-compressed number of keys in an animation always equals the (number of bones)*(number of frames) that were exported.

ImportSeqs=1 signifies that the animation sequence info embedded into the binary .PSA file by the Max exporter is to be used.

You can still specify animation sequences just like the old format, except that it's done through #exec ANIM commands and they're now tied to the animation object, rather than the mesh:


In any case, a specific DIGEST command needs to be issued, at which point all sequences (implicit and declared) are compressed into the internal key track format:


Specify VERBOSE to see more information in UCC.log after the rebuild.

Notification callbacks need to be placed after the #exec ANIM DIGEST, and have a syntax similar to the old notify commands:

#exec ANIM NOTIFY ANIM=SkeletalAnimation1 SEQ=All TIME=0.1 FUNCTION=LandThump

A UAnimation object is linked to a certain skeletal mesh at runtime using LinkSkelAnim:

function PostBeginPlay()
    LinkSkelAnim(Animation'SkeletalAnimation1' );

Or (more useful for backward compatibility)  it can be linked at compile time using:


LOD works the same as regular LOD in Unreal Tournament.  See LODTechnologyNotes.htm.

When your skeletal animation makes your character cover an area far outside its reference pose or root position, you have the option to override the bounding box extents that the engine uses to determine visibility. 

#exec MESH BOUNDINGBOX MESH=MeshSk XMIN=-64.0 YMIN=-64.0 ZMIN=-64.0 XMAX=64.0 YMAX=64.0 ZMAX=64.0

There is a tradeoff: make the bounding box too big, and the mesh will be drawn in situations where it is occluded by architecture; make it too small, and meshes may flicker in and out of view.


The names of the multi/sub materials indicate which rendering modes will be activated for the polygon flags. The following strings fragments, with the familiar Unreal polygon effects, can be anywhere in the material name and can be combined (if the combination makes sense to the engine.)

Recommended: when using multiple textures, always name them skin00, skin01, etc, which will force the 'multiskin' indices to point at the textures in a predictable order.

  • skinXX -  give your materials numbered skin names to ensure they are linked in the right order, whenever you have multiple skins for a single mesh.
  • twosided - twosided (flags, fins)
  • weapon (obsolete) See Weapon Bone.
  • invisible (obsolete)
  • modul - modulated
  • mask  - masked
  • envir   - environment mapped
  • mirro  - environment mapped
  • nosmo - 'nosmooth', non-bilinear filtered
  • unlit - unlit
  • trans - translucent

You still have to create your own 8-bit .pcx or .bmp versions of texture files and manually link them up in the appropriate .uc script files, but you can look at the X_ModelInfo.log output to see exactly which bitmap files go with what material number for your model.

Log Files

The exporter does not output explicit '.uc' template script files, instead it writes X_AnimInfo.log and X_ModelInfo.log which contain a detailed summary of the exported data, and have all the information about frames and material/bitmaps you need when writing the script #exec commands that link in the data.

The log files are always dumped in the same folder along with the .PSA/.PSK files.

Weapon Bone

Instead of assigning a polygon in Max, you now assign any bone as a weapon-carrier using MESH WeaponAttach, with the name of the bone as visible in Max:


The actual position can be fixed up. (so you're not forced to link an extra bone to the skeleton to achieve the right position)

#exec MESH WEAPONPOSITION MESH=MeshSk YAW=50 PITCH=0 ROLL=10 X=0.0 Y=0.0 Z=0.0

This attachment point is then fully backward compatible with Unreal Tournament's weapon polygon.

Important notes

  • When setting up a skeleton, regardless of whether you're using Max or Maya, make sure each and ever bone/joint has a unique name. Take special care to do this after you've constructed a skeleton using mirroring. The code that resolves the hierarchy and linkups, both in the exporter and in the engine, assumes that unique names are used.
  • The visibility bounding-box extents are determined from the reference pose, not the entire range of animations as was the case for  vertex animations. To compensate for the possibility that animations extend far beyond the bounds of the reference pose, the code currently uses the reference pose limits and scales those out once more, to estimate a safe size as used for visibility determination. If meshes still flicker, it may be because the animations that were exported stray too far from their reference pose / origin position, and move beyond the boundaries where the engine expects it to be. You can override the bounding box extents with the "BOUNDINGBOX" #exec command.
  • Skins: the best way to currently guarantee that the order of skins isn't messed up is to strictly follow "skin00, skin01.." naming conventions for your multi/sub materials in Max.
  • Root pose issues: to prevent anomalous vertex assignments slipping in when exporting the .PSK file, it is recommended to export it from either an explicit root pose (as can be activated with bipeds in Character Studio) or in any case, make sure frame 0 is reachable as part of the active time slider so the exporter does not get confused with the skin's versus the bones' reference poses.
  • When the mesh shows messed up in the engine, it's usually a matter of the .PSK not matching the .PSA.  This can happen even if they're exported from the same Max file in some cases. Reference skin PSK files  are saved from the first available frame; when the first frame is hidden, and the animation bar is set to show only a subset of the frames, the exporter may get confused and associate the bone reference pose with the wrong skin reference pose.   It's easiest to keep a special original .max file which contains this 'reference pose', the right skin/material linkup, and no animation, so you can always rely on that as the source for the .PSK file, without having to mess with the start-time of animations.
  • Orientation/height problems: due to the different 3D axis assignments in Unreal, Max and Maya, if no adjustments are applied, Max characters come out turned 90' sideways, and Maya characters turned on their backs. Also, in most cases it is convenient to have feet placed on the zero plane when editing/animation characters, while the engine may, depending on game code, rely on some actors (like player models) to be centered around zero instead.
    Orientation and height can be adjusted in script (at rebuild time, rather than engine-runtime)
    right after the .PSK import statement, using the MESH ORIGIN commands:

    Typical maya orientation adjustment:
    #exec MESH ORIGIN MESH=PistonMesh X=0 Y=0 Z=-32 YAW=64 PITCH=00 ROLL=64
    Max player height adjustment:
    #exec MESH ORIGIN MESH=WarBossMesh X=0 Y=0 Z=90 YAW=0 PITCH=0 ROLL=0

[end of document | back to top]

Copyright Epic Games 2000

Erik de Neve | erik@epicgames.com