Basic Animation Tutorial


This guide aims at enabling modders to create very simple animated objects by applying pre-assembled basic animation files. Furthermore these animation files may be customized to allow for a multitude of more complex animations.
This might especially be geared towards modders who don't have access to or knowledge about using 3D applications (such as 3D Studio Max) to create and export animations.
Basic knowledge about animations and about using NifSkope is required though.

Feel free to add to this article and/or correct any mistakes you might come across as this guide does neither claim to be complete nor to be 100% accurate.

File:AnimGuide Samples.gif
Examples of objects utilizing simple animations. Click to enlarge.
Tools used in this tutorial

Required

Optional


Anatomy of AnimationsEdit

File:AnimGuide Fig 1 Branch Overview.gif
Fig. 1: Typical view on a simple animation's block tree.

An animation sequence that's embedded into a .nif file is composed of characteristic block structures (see Fig. 1).
The following is a list of brief descriptions about the most common elements.

Controller ManagersEdit

File:AnimGuide Fig 2 No Blank Links Allowed.gif
Fig. 2: Example of a harmful Controller Sequences setup.

Basically stores links to the Controller Sequences. Will be created automatically when using NifSkope's Attach .KF spell.

Note: There mustn't be any blank links inside the Controller Sequences array or the game will crash when attempting to load the .nif file.

Controller SequencesEdit

Controller Sequences make up the actual animation and are the sole content of .kf files. They contain Blocks of information consisting of Interpolator and Controller links as well as several string variables specifying targets, types and sometimes certain parameters of animation controllers. The name of the Controller Sequence is also important as it serves as a parameter for certain animation script commands (e.g. PlayGroup). In the case of PlayGroup you can only use a specific set of names to be recognized as correct by the script compiler (see AnimGroups).

Note: Naming a Controller Sequence Idle will make the object use that animation automatically and possibly override other animation sequences that are triggered via script if the Cycle Type value of the NiControllerSequence block is set to CYCLE_LOOP.

Animation ControllersEdit

Contain certain interpolator blocks as well as as data blocks in turn containing the actual keyframe data.

  • NiTransformControllers
Transform Controllers are used to apply translation, rotation and/or scaling to NiTriShapes, NiTriStrips or NiNodes. This means you can make your object or parts of it dynamically move around, swivel, shrink/grow, etc.
  • NiTextureTransformControllers
Similar to Transform Controllers, but must target a NiTexturingProperty. You can use it to affect the UV coordinates of the targeted mesh. In other words, you can make a texture scroll, spin or zoom in/out.

Note: The texture you're trying to affect mustn't have a normal map for this to work correctly.

  • NiAlphaControllers
Alpha Controllers are used to affect an object's opacity. They must target NiMaterialProperty blocks and in most cases the mesh node (NiTriStrips/NiTriShape) needs to have a NiAlphaProperty attached to it. Using Alpha Controllers you can make objects smoothly fade in or out; partial transparency is also possible, but unfortunately behaves a little glitchy since the alpha values can and will get overridden by the game's built-in distant Object/Item Fade feature.

Note: The texture you're using on the fading mesh node needs to have a normal map for this to work correctly.

  • NiVisControllers
Vis Controllers toggle visibility of Nodes meaning you can dynamically switch objects or parts of them on/off visually. Can also be used in conjunction with NiAlphaControllers to circumvent Object/Item Fade issues.

Animation InterpolatorsEdit

Certain types of controllers need certain types of interpolators. Interpolators can either store a single keyframe value or point to a Data block.

  • Animation Data blocks
Contain keyframe information for a specific animation controller. In other words, they specify the values of certain variables (e.g. translation, rotation, scale, opacity, visibility, etc.) at specific points in time of the animation and how to interpolate in-between.


Step-by-step guidesEdit

The following is a list of instructions about how to set up a certain simple animation in a .nif and about how to tweak it afterwards if needed.

File:AnimGuide Fig 3 Basic Nif Setup.gif
Fig. 3: The basic .nif branch setup that is required before attaching one of the provided animation sample files.
  1. Download sample package here
  2. Open your .nif file in NifSkope and set it up similar to how it was done in Fig. 3.

Note: For the sample .kf files to be attachable it is crucial to have a Base NiNode like in the example. For some of the samples it is necessary to have either another NiNode named Branch and/or to rename your mesh node to Target.
Also adding a BSX Flags Extra Data block to the Base NiNode and setting its Flags value to a certain number ('11' is confirmed to work in all provided examples) is a requirement for animations to function properly.

  1. Decide on what sample animation file to attach. Possible choices so far:

Note: Attaching is done via selecting Spells -> Animation -> Attach .KF in NifSkope - you'll need at least version 0.9.5 or it will spawn an error message about the .kf file containing too many root nodes.




Creating a Transform Controller animationEdit

  1. Attach anim_scale.kf and you're done - the 2 animation sequences in it target the Branch NiNode and will make it shrink from 1.0 to 0.0 and vice versa in 1.5 seconds (see example_scale.nif inside the sample package for an example object using this technique)


If you don't want your targeted object to (solely) behave like that see Tweaking an animation.

File:AnimGuide Fig 4 Assigning Target.gif
Fig. 4: Assigning a target in NifSkope.

Creating a Visibility Controller animationEdit

  1. Attach anim_visibility.kf - the 2 animation sequences in it target the Branch NiNode and will make it disappear almost instantly (see example_visibility.nif inside the sample package for an example object using this technique)

Note: NifSkope will spawn an error message when trying to save the file after attaching the .kf file.

This is due to a missing target link in the NiVisController that is contained in the .kf file. You can fix this via assigning a target - simply enter the node number of the Branch NiNode into the Target Block Details entry of the NiVisController (see Fig. 4).

The animation will work without applying these fixes though.


If you don't want your targeted object to behave like that see Tweaking an animation.

Creating an Alpha Controller animationEdit

  1. Attach anim_alpha.kf - the 2 animation sequences in it target the NiMaterialProperty of the Target mesh node and will make it fade in/out in 1.5 seconds (see example_alpha.nif inside the sample package for an example object using this technique)

Note: A NiVisController was added to circumvent the alpha values getting overridden by the game's Object/Item Fade feature.

Furthermore NifSkope will spawn an error message when trying to save the file after attaching the .kf file.
This is due to a missing target link in both the NiAlphaController and the NiVisController that are contained in the .kf file. You can fix this via assigning a target, simply enter the node numbers of the NiMaterialProperty of the Target mesh node and of the Branch NiNode into the Target Block Details entry of the NiAlphaController respectively NiVisController (similar to Fig. 4).
Also the NiMultiTargetTransformController, which will be created automatically, is targeting the Target mesh node (which will cause an error message, too); simply remove the NiMultiTargetController block as it is not needed there anyway.

The animation will work without applying any of these fixes though.


If you don't want your targeted object to behave like that see Tweaking an animation.

Creating a Texture Transform Controller animationEdit

  1. Attach anim_textransf.kf - the 2 animation sequences in it target the NiTexturingProperty of the Target mesh node and will make its texture scroll to the right/left in 1.5 seconds (see example_textransf.nif inside the sample package for an example object using this technique)

Note: NifSkope will spawn an error message when trying to save the file after attaching the .kf file.

This is due to a missing target link in the NiTextureTransformController that is contained in the .kf file. You can fix this via assigning a target - simply enter the node number of the NiTexturingProperty of the Target mesh node into the Target Block Details entry of the NiTextureTransformController (similar to Fig. 4).
Also the NiMultiTargetController, which will be created automatically, is targeting the Target mesh node (which will cause an error message, too); simply remove the NiMultiTargetController block as it is not needed there anyway.

The animation will work without applying any of these fixes though.


Note:The texture animation won't work on a texture that has a normal map. You must set the emissive colour contained in the MaterialProperty of the targeted NiTriStrips to White (ffffff) instead of the default Black, for a texture without a normal map to show up ingame..


If you don't want your targeted object to behave like that see Tweaking an animation.



File:AnimGuide Fig 5 Changing Animation Time Frame.gif
Fig. 5: Updating the animation's global time frame after adjusting keyframe values.

Tweaking an animationEdit

The provided .kf files contain animations of the most basic kind.
The following list contains information how to tweak the aforementioned attached animations.

Note: If you are to change the keyframes' time values to exceed the default 1.5 seconds you'll have to edit the Stop Time value inside the NiControllerSequence accordingly or else the game will ignore any of these keyframes.

Tweaking a Transform Controller animationEdit

  • Altering the Scaling:
    • Locate and select the NiTransformData block inside a NiControllerSequence (see Fig. 6 if you have trouble finding it).
    • Inside the Block Details list expand the Scales entry.
    • Increase the number of scale keys if desired and update their array.
    • Edit the Time and Value settings of your animation keys to your liking.
    • Repeat for other NiControllerSequences if desired.
 
Fig. 6: Relative position of a Ni[..]Data block.

Note: Change Num Keys to 0 to get rid of scaling for good.

  • Adding Translations:
    • Locate and select the NiTransformData block inside a NiControllerSequence(see Fig. 6 if you have trouble finding it).
    • Inside the Block Details list expand the Translations entry.
    • Change the Num Keys entry's value to at least 2 and update the Keys array.
    • Change the Interpolation value to 1 or 2 (LINEAR respectively QUADRATIC).
    • Edit the Time and Value settings of your animation keys to your liking.
    • Repeat for other NiControllerSequences if desired.
  • Adding Rotations:
    • Locate and select the NiTransformData block inside a NiControllerSequence (see Fig. 6 if you have trouble finding it).
    • Inside the Block Details list change the Num Rotation Keys entry's value to at least 2.
    • Change the Rotation Type value to 1,2 or 3 if you want to use Quaternion Keys or to 4 if you want to use XYZ Rotations and update the respective array
    • Quaternion keys work exactly like rotation values inside other node types (e.g. NiTriStrips, NiNode, etc.).
    • For XYZ Rotations you'll be facing another 3 arrays of key data, one for each axis (see figure E).

      Note: Angles inside XYZ Rotations are measured in radians
      (as in Pi = 3.1416 = 180°)

    • Change the Interpolation value to 1 or 2 (LINEAR respectively QUADRATIC).
    • Edit the Time and Value settings of your animation keys to your liking.
    • Repeat for other NiControllerSequences if desired.


Tweaking a Visibility Controller animationEdit

  • Locate and select the NiBoolData block inside the NiBoolInterpolator in turn inside a NiControllerSequence (similar to Fig. 6 in case you have trouble finding it).

Note: NiVisController keyframe data must use the UNKNOWN_KEY interpolation type.

  • Increase the Num Keys value and update the Keys array if desired.
  • Edit the Time and Value settings of your animation keys to your liking.

Note: Only 1 (=visible) and 0 (=invisible) are valid input for the Value entry.

  • Repeat for other NiControllerSequences if desired.


Tweaking an Alpha Controller animationEdit

  • Locate and select the NiFloatData block inside the NiFloatInterpolator in turn inside a NiControllerSequence (similar to Fig. 6 in case you have trouble finding it).
  • Increase the Num Keys value and update the Keys array if desired.
  • Edit the Time and Value settings of your animation keys to your liking.
  • Repeat for other NiControllerSequences if desired.

Note: Changing settings in the NiAlphaProperty of the mesh node can create interesting results when seen in motion, feel free to experiment.


 
Fig. 7: Example showing how to find the Interpolator block which is in charge of translating a texture along the V axis.

Tweaking a Texture Transform Controller animationEdit

There's about 5 operations you can do via Texture Transform Controllers:

  • move textures along U axis (left/right)
  • move textures along V axis (up/down)
  • rotate textures
  • scale textures along U axis
  • scale textures along V axis


In the sample anim_textransf.kf file each of these operations is included, but only one of them has keyframe data that has an actual impact on the visual outcome. Each operation has its own NiFloatInterpolator complete with a NiFloatData block. To find the right one you'll have to:

  • Select the NiControllerSequence block.
  • Expand the Controlled Blocks entry and its sub-entries in the Block Details list.
  • Search the Blocks for entries labeled Variable Offset 1, there you will find String values determining the operation that the NiFloatInterpolator's assigned to
    (see Fig. 7).
  • If you found the right Block containing info for the operation you would like to modify check the Interpolator link inside that very same Block - it'll lead you to the NiFloatData block you'll have to edit then, which is similar to most other kinds of data blocks:
    • Increase the Num Keys value and update the Keys array if desired.
    • Edit the Time and Value settings of your animation keys to your liking.

      Note: UV coordinates are usually values between 0 and 1, so translating by a value of 2 along an axis will make the texture completely scroll over the mesh twice.
      Changing values for scaling will work quite the other way round though, the higher the value the smaller the texture will become - it'll be repeating itself along the edges in that case.

    • Repeat for other NiFloatData blocks and/or NiControllerSequences if desired.


Final WordsEdit

Further iterations of this guide may include instructions about how to merge multiple controllers into a single controller sequence and maybe provide example files for this.
Currently, there's also an .esp file included in the package which places all example files on a table in the TestingHall cell (type 'coc testinghall' in the in-game console to get there).