/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])