Armature movement in the game engine (working)

/edit- thanks ideasman42 for showing me the direct pose IPO recording, and Osobna Stranka who made the location/rotation recording script in the game engine edit/

The following is how to record armature movement in the game engine:

* Have an armature with a timer property called "time".
* Attach the following to an always sensor set to no pulse mode (so it runs only when the game starts).
 #RecArmInit.py



import Blender
from Blender import *

contr = GameLogic.getCurrentController()
gameObj = contr.getOwner()
name = gameObj.getName()[2:]
a=Armature.Get(name)
c=Object.Get(name).getPose()

gameObj.RECORD_DELAY=10

arm_ob=Object.Get(name)
pose= arm_ob.getPose()
pose_bones= pose.bones

try:
    GameLogic.ArmRec=GameLogic.ArmRec
except:
    GameLogic.ArmRec=[]

try:   
    for items in GameLogic.ArmRec:
        for item in items:   
            if item[2]==name:
                del item
except:
    arm_ob=arm_ob

action=arm_ob.getAction()
frame = int(25*gameObj.time)

try:   
    gameObj.NLA_BEGINFRAME = gameObj.NLA_BEGINFRAME
except:
    gameObj.NLA_BEGINFRAME = frame
# this was edited from original posting
for b in c.bones.keys():
    try:

        ipo=action.getAllChannelIpos()[b]

        pending=[]

        pending.append(pose.bones[b])
        pending.append(pose_bones[b])
        pending.append(name)

        standing=[]

        try:
            curve_xsize= ipo[Blender.Ipo.PO_SCALEX]
            curve_ysize= ipo[Blender.Ipo.PO_SCALEY]
            curve_zsize= ipo[Blender.Ipo.PO_SCALEZ]
           
            curve_xsize.interpolation= \
            curve_ysize.interpolation= \
            curve_zsize.interpolation= \
            Blender.IpoCurve.InterpTypes.LINEAR
       
            standing.append(['S',curve_xsize,curve_ysize,curve_zsize])
        except:
            name=name

        try:
            curve_xloc= ipo[Blender.Ipo.PO_LOCX]
            curve_yloc= ipo[Blender.Ipo.PO_LOCY]
            curve_zloc= ipo[Blender.Ipo.PO_LOCZ]
       
            curve_xloc.interpolation= \
            curve_yloc.interpolation= \
            curve_zloc.interpolation= \
            Blender.IpoCurve.InterpTypes.LINEAR
            standing.append(['L',curve_xloc,curve_yloc,curve_zloc])
        except:
            name=name

        try:
            curve_wquat= ipo[Blender.Ipo.PO_QUATW]
            curve_xquat= ipo[Blender.Ipo.PO_QUATX]
            curve_yquat= ipo[Blender.Ipo.PO_QUATY]
            curve_zquat= ipo[Blender.Ipo.PO_QUATZ]
           
            curve_wquat.interpolation= \
            curve_xquat.interpolation= \
            curve_yquat.interpolation= \
            curve_zquat.interpolation= \
            Blender.IpoCurve.InterpTypes.LINEAR
            standing.append(['R',curve_wquat,curve_xquat,curve_yquat,curve_zquat])
        except:
            name=name

        pending.append(standing)
        GameLogic.ArmRec.append(pending)
    except:
        name=name
*  Attach the following script to an always sensor set to 2 pulses
#RecArm.py


import Blender
from Blender import *

contr = GameLogic.getCurrentController()
gameObj = contr.getOwner()

contr = GameLogic.getCurrentController()
gameObj = contr.getOwner()
name = gameObj.getName()[2:]

if gameObj.RECORD_DELAY !=0:
    gameObj.RECORD_DELAY -= 1



frame = int(25*gameObj.time)

if hasattr(GameLogic, 'ArmRec'):
       
    for rec in GameLogic.ArmRec:

        if rec[2]==name:

            for keys in rec[3:]:

                for key in keys:

                    if key[0]=='S':

                        if [key[1].__getitem__(frame),key[2].__getitem__(frame),key[3].__getitem__(frame)] != [rec[0].size[0],rec[0].size[1],rec[0].size[2]]:

                            key[1].append((frame-1, key[1].__getitem__(frame-1)))
                            key[2].append((frame-1, key[2].__getitem__(frame-1)))
                            key[3].append((frame-1, key[3].__getitem__(frame-1)))
                   
                            key[1].append((frame, rec[1].size[0]))
                            key[1].update()
                            key[2].append((frame, rec[1].size[1]))
                            key[2].update()
                            key[3].append((frame, rec[1].size[2]))
                            key[3].update()
                         
                    if key[0]=='L':
                        if [key[1].__getitem__(frame),key[2].__getitem__(frame),key[3].__getitem__(frame)] != [rec[0].loc[0],rec[0].loc[1],rec[0].loc[2]]:
                            key[1].append((frame-1, key[1].__getitem__(frame-1)))
                            key[2].append((frame-1, key[2].__getitem__(frame-1)))
                            key[3].append((frame-1, key[3].__getitem__(frame-1)))
                       
                            key[1].append((frame, rec[1].loc[0]))
                            key[1].update()
                            key[2].append((frame, rec[1].loc[1]))
                            key[2].update()
                            key[3].append((frame, rec[1].loc[2]))
                            key[3].update()
              
                    if key[0]=='R':
                        if [key[1].__getitem__(frame),key[2].__getitem__(frame),key[3].__getitem__(frame),key[4].__getitem__(frame)] != [rec[0].quat[0],rec[0].quat[1],rec[0].quat[2],rec[0].quat[3]]:
       
                            key[1].append((frame-1, key[1].__getitem__(frame-1)))
                            key[2].append((frame-1, key[2].__getitem__(frame-1)))
                            key[3].append((frame-1, key[3].__getitem__(frame-1)))
                            key[4].append((frame-1, key[4].__getitem__(frame-1)))
                   
                            key[1].append((frame, rec[1].quat[0]))
                            key[1].update()
                            key[2].append((frame, rec[1].quat[1]))
                            key[2].update()
                            key[3].append((frame, rec[1].quat[2]))
                            key[3].update()
                            key[4].append((frame, rec[1].quat[3]))
                       

 
* Make a blank action and set Rot, Loc, Size or some combination of the them to select bones. The movements that will be recorded are those that have a key frame, and this also pertains to attributes (eg a bone without a size key will not have it's size recorded)
* I suggest you save before you use the game engine, simply because the script runs fastest with a mostly blank action. Besides that, the script will record armature movement on the armatures you have the script on.

NOTE- the first python script should be higher in the logic bricks than the second.

The script does slow down after a while, depending on how many keys are being recorded. The following script is not needed to record, but will speed up the game engine if the script slows the game engine down. (the script should be attached to a keyboard press, or other user executed method , and be above the other two scripts in the logic bricks. The same thing that triggers this script should trigger “RecArmInit.py” as well) The script makes a new action and saves the old one to the NLA editor.

#newAct.py
import Blender
from Blender import *

contr = GameLogic.getCurrentController()
gameObj = contr.getOwner()
 
if gameObj.RECORD_DELAY==0:

    name = gameObj.getName()[2:]
    frame = int(25*gameObj.time)

    action= Object.Get(name).getAction().getName()

    Blender.Object.Get(name).actionStrips.append(Blender.Armature.NLA.GetActions()[action])

    Blender.Object.Get(name).actionStrips[-1].stripEnd = frame
    Blender.Object.Get(name).actionStrips[-1].stripStart = gameObj.NLA_BEGINFRAME

    act = Armature.NLA.NewAction(action)
    act.setActive(Object.Get(name))

    gameObj.NLA_BEGINFRAME = frame
   

    if hasattr(GameLogic, "ArmRec"):
        for items in GameLogic.ArmRec:
            if items[2]==name:
                for bones in items[3:]:
                    for key in bones:
                        if key[0]=="S":
                            items[0].insertKey(Object.Get(name), frame, [Object.Pose.SIZE])
                        if key[0]=="L":
                            items[0].insertKey(Object.Get(name), frame, [Object.Pose.LOC])
                        if key[0]=="R":
                            items[0].insertKey(Object.Get(name), frame, [Object.Pose.ROT])
                        

Very nice TurboRage. Thanks!

This is giving errors :

 #RecArmInit.py
           
<b>             curve_xsize.interpolation= \
            curve_ysize.interpolation= \
            curve_zsize.interpolation= \
            Blender.IpoCurve.InterpTypes.LINEAR</b>
       
    
            curve_xloc.interpolation= \
            curve_yloc.interpolation= \
            curve_zloc.interpolation= \
            Blender.IpoCurve.InterpTypes.LINEAR
       
           
            curve_wquat.interpolation= \
            curve_xquat.interpolation= \
            curve_yquat.interpolation= \
            curve_zquat.interpolation= \
            Blender.IpoCurve.InterpTypes.LINEAR
             

Was it supposed to be a shortcut for : ?


            curve_wquat.interpolation= Blender.IpoCurve.InterpTypes.LINEAR
            curve_xquat.interpolation= Blender.IpoCurve.InterpTypes.LINEAR
            curve_yquat.interpolation= Blender.IpoCurve.InterpTypes.LINEAR
            curve_zquat.interpolation= Blender.IpoCurve.InterpTypes.LINEAR


This gives an error : (RECORD_DELAY not exist). I assume it’s a timer property to be added to the armature ?


if gameObj.RECORD_DELAY !=0:
    gameObj.RECORD_DELAY -= 1
      

Mike

OK, updating, the script did have an error, there was an uppercase B representing a variable in the first script that should have been lower case… I don’t know how that got changed.
Mike- I am not sure, but I think the reason you are getting “RECORD DELAY” does not exits is because you have the second script before the first in the logic brick line up, causing the variable to be called before it is initialized.
Anyway, I test ran the script to make sure it worked now, in its current form (I should have done so before…) If there are any other problems with the script, please post them. Also, if it works, please post so I can be sure… Also script works with python 2.43

Ok I have it working now.

Buck-Beaver,

There is something “wonky” with the mouse rig.

E.g. If I move the “base” bone, the mesh is getting left behind. If the head bone is rotated, the eyes are popping out of the head.

I’ll take a look at the original mouse rig and try to set it up in the game engine and see if I run into the same problem, or can see what the difference is with your file.

Mike

Thanks for replying, just wanted to know the posted scripts were workable. :slight_smile:

Thanks Mike, the Mouse Rig was really just a quick test for the Panda Puppet/Blender Machinima project and the original author (Clean3D I think?) I do not think intended for it to be used in the GE. I am working on putting together a low-poly character that is scratch-built for this kind of thing.