SetAnimRootMotion entity,node_name$[,apply][,vertical][,yaw]
Parameters
|
entity - handle of an animated entity node_name$ - name of the animated node to take the motion from, or a slash-separated path apply (optional) - True to let the engine move the entity itself; False (default) vertical (optional) - True to extract up-and-down movement as well; False (default) yaw (optional) - True to extract turning about the up axis; True (default) |
Description
|
Turns on root motion for an entity: the movement baked into one animated node is taken out of the displayed pose and handed to you as a per-update delta. Animators often build a walk cycle that genuinely travels forward, so the feet plant properly instead of skating. Played back as-is, the character wanders away from its own entity origin. Root motion fixes that: the travel is stripped out of the skeleton, the character animates on the spot, and you get the distance it would have covered so the entity can be moved by exactly that much. Sideways and forward translation is always extracted. vertical adds Y, which you want for jumps and vaults and not much else. yaw, on by default, extracts turning so an animated turn-in-place actually rotates the entity. Scale, pitch and roll are left on the node. With apply False - the default - nothing moves by itself: read AnimRootMotionX, AnimRootMotionY, AnimRootMotionZ and AnimRootMotionYaw after each UpdateWorld and feed them into whatever moves your character, whether that is MoveEntity, a character controller or a physics body. With apply True the engine moves and turns the entity for you before the normal collision pass, so classic Blitz collisions still push back on the animated movement. A character driven by a Box3D dynamic body should always use apply False and pass the deltas to the body itself, rather than letting two systems fight over the same transform. The node is looked up like FindBone: exact name first, then case-insensitively, with a slash-separated path when names repeat. It does not have to be a skin joint - glTF files often animate an armature or model root that sits above the real joints, and that node is usually the right source. A name that matches no animated node raises an error. Root motion is deliberately opt-in, because plenty of models carry accidental drift on their hip node and plenty of games would rather drive movement entirely from code. Switching it on, changing the source node or restarting a clip resets the reference pose and reports a zero delta for that update instead of teleporting the character. See also: ClearAnimRootMotion, AnimRootMotionX, AnimRootMotionZ, AnimRootMotionYaw, FindBone. |
Example
; SetAnimRootMotion Example ; ------------------------- Graphics3D 640,480,0,2 SetBuffer BackBuffer() camera=CreateCamera() PositionEntity camera,0,3,-8 RotateEntity camera,15,0,0 light=CreateLight() RotateEntity light,45,45,0 ground=CreatePlane() EntityTexture ground,LoadTexture("media/MossyGround.BMP") ; A courier robot: a named pivot with a cube body courier=CreatePivot() NameEntity courier,"CourierRoot" body=CreateCube(courier) ScaleEntity body,0.4,0.4,0.6 PositionEntity body,0,0.4,0 EntityColor body,60,220,255 ; Author a patrol animation whose keys carry the robot 8 units along X PositionEntity courier,-4,0,0 SetAnimKey courier,0 PositionEntity courier,4,0,0 SetAnimKey courier,60 patrol=AddAnimSeq(courier,60) PositionEntity courier,-4,0,0 ; SetAnimRootMotion strips that movement out of the displayed pose and, ; with apply=True, moves the entity itself instead apply=True SetAnimRootMotion courier,"CourierRoot",apply,False,False ; Play the patrol ping-pong so the robot shuttles back and forth CrossFadeAnim courier,patrol,0,2 While Not KeyDown(1) ; Space re-calls SetAnimRootMotion with apply flipped: with apply=False ; the extracted movement is discarded and the robot marches on the spot If KeyHit(57) apply=1-apply SetAnimRootMotion courier,"CourierRoot",apply,False,False EndIf UpdateWorld ; Arrow keys move the camera If KeyDown(200) Then MoveEntity camera,0,0,0.1 If KeyDown(208) Then MoveEntity camera,0,0,-0.1 If KeyDown(203) Then TurnEntity camera,0,1,0 If KeyDown(205) Then TurnEntity camera,0,-1,0 RenderWorld Text 0,0,"Space: toggle apply Arrows: camera Esc: exit" Text 0,20,"SetAnimRootMotion courier,"+Chr$(34)+"CourierRoot"+Chr$(34)+","+apply+",False,False" Text 0,40,"Root delta X: "+AnimRootMotionX(courier)+" EntityX: "+EntityX(courier) Flip Wend End
Index