From BlenderWiki

Jump to: navigation, search
Note: This is an archived version of the Blender Developer Wiki. The current and active wiki is available on wiki.blender.org.

Overview

The goal of the project is to provide better access to existing animation tools and then add a few more (e.g., layers). You can find the full proposal here.

New Animation System

Goal

The BGE should have an animation system that is independent of the actuator code. The current system just has actuators handle all of the animations. This seems backwards. The actuators should make use of a centralized animation system. By using a centralized system, different animation types can be unified into "actions" similar to the way Blender 2.5 handles animations. While internally they are still distinct types, to the user they appear as one type. The system wont be a complete recode of animations in the BGE (that's for another project), but is rather a way of consolidating animation code in the BGE. To start with, it will just take the code from the various actuators and put them in the same spot. It is meant more of a refactor/cleaning of the codebase than it is a cool new feature. That being said, the new system should also include the concept of animation layers and layer blending. It should also retain all of the features currently found in the actuators. Furthermore this system should be accessible by Python as well as logic bricks.

Current

  • The system has been created and supports most of the features found in the Action, F-Curve and Shape Action Actuators.
  • Layers have been implemented and layer blending is supported for armature actions.
  • Python API has been created (KX_GameObject.playAction()).
Visual overview of the new animation system in the BGE

ToDo

  • Layer blending for shape actions needs to be implemented. Pending: nothing

Logic Bricks

Goal

Have a single Action Actuator. The F-Curve Actuator and Shape Action Actuators should be removed and converted for older files. The Action Actuator should be able to handle all action types.

Current

  • The F-Curve Actuator has been combined into the Action Actuator.
  • The Shape Action Actuator has been combined into the Action Actuator.
  • The F-Curve and Shape Action Actuators are no longer available and are converted to Action Actuators.
  • All play modes should be working correctly now.
  • Layer and layer weight are settable via the actuator.

ToDo

  • Nothing

Bug Fixes

ToDo

  • Gather a list of bugs

Bugs

Python API

Here is the current API (raw rst):
.. method:: playAction(name, start_frame, end_frame, layer=0, priority=0, blendin=0, play_mode=ACT_MODE_PLAY, layer_weight=0.0, ipo_flags=0, speed=1.0)

  Plays an action.
  
  :arg name: the name of the action
  :type name: string
  :arg start: the start frame of the action
  :type start: float
  :arg end: the end frame of the action
  :type end: float
  :arg layer: the layer the action will play in (actions in different layers are added/blended together)
  :type layer: integer
  :arg priority: only play this action if there isn't an action currently playing in this layer with a higher (lower number) priority
  :type priority: integer
  :arg blendin: the amount of blending between this animation and the previous one on this layer
  :type blendin: float
  :arg play_mode: the play mode
  :type play_mode: KX_ACTION_MODE_PLAY, KX_ACTION_MODE_LOOP, or KX_ACTION_MODE_PING_PONG
  :arg layer_weight: how much of the previous layer to use for blending (0 = add)
  :type layer_weight: float
  :arg ipo_flags: flags for the old IPO behaviors (force, etc)
  :type ipo_flags: int bitfield
  :arg speed: the playback speed of the action as a factor (1.0 = normal speed, 2.0 = 2x speed, etc)
  :type speed: float

.. method:: stopAction(layer=0)
  
  Stop playing the action on the given layer.
  
  :arg layer: The layer to stop playing.
  :type layer: integer
  
.. method:: getActionFrame(layer=0)

  Gets the current frame of the action playing in the supplied layer.
  
  :arg layer: The layer that you want to get the frame from.
  :type layer: integer
  
  :return: The current frame of the action
  :rtype: float
  
.. method:: setActionFrame(frame, layer=0)

  Set the current frame of the action playing in the supplied layer.
  
  :arg layer: The layer where you want to set the frame
  :type layer: integer
  :arg frame: The frame to set the action to
  :type frame: float

.. method:: isPlayingAction(layer=0)

   Checks to see if there is an action playing in the given layer.
   
   :arg layer: The layer to check for a playing action.
   :type layer: integer
   
   :return: Whether or not the action is playing
   :rtype: boolean

And here is an example where a base idle (IdleBase) is combined with an idle animation for the top part of the character (IdleTop). The IdleTop could be changed out but the base (mostly the legs) would still be going. This is especially useful for things like running and attacking.
#Example
import bge

ob = bge.logic.getCurrentController().owner
ob.playAction('IdleBase', 1, 200, layer=0, play_mode=bge.logic.KX_ACTION_MODE_LOOP)
ob.playAction('IdleTop', 1, 300, layer=1, play_mode=bge.logic.KX_ACTION_MODE_LOOP)
In this example, ob is an armature object, but playAction() is available to all objects.

Migration Guide

While a great deal of effort was put into keeping existing animation setups from breaking in Pepper, some of the changes to the core system have made it difficult. There are currently a few things to keep in mind for making sure your setups work in Pepper:
First off, in trunk the actuators are always playing from when they receive a positive pulse to when they receive a negative pulse. Even if you can't see an action playing, it is still being tracked and is attempting to override other currently playing actions. In Pepper actions are more discrete and only attempt to play when they receive a positive pulse. This means if you may need to make use of pulse mode to make certain actuators work. For example, it is common to have some form of idle action on an always sensor that just loops. This way, when no other actions are playing, the idle takes over. For porting this type of setup to Pepper, the always sensor needs to have positive pulse mode enabled. This way the actuator will keep attempting to play the action.
The issues with pulses should now be fixed. If you're still having problems, please file a bug report.
Also related to the other issue is blending actions. In trunk since actions are always playing, they can be mixed as long as they aren't using the same channels. In Pepper, only one action can occupy a layer. This means, that if you were relying on Action Actuators to blend your actions, you now have to change your setup to use layers instead.
These are currently the only known breaking changes. Anything else should be considered a bug and reported to Moguri.
BGE pepper action actuator.png
There are also some changes that shouldn't break current setups, but are still good to know about. For example, the F-Curve and Shape Action actuators no longer exist. Instead, everything is now handled by the Action actuator. F-Curve and Action actuators should be automatically converted to Action actuators when loading a file from trunk. You might want to double check the converted actuators to make sure things didn't break in the conversion.