-- Animation blending: three Foxes. The left one walks, then crossfades to a run over a second; -- the middle one walks on the base layer while Survey plays on layer 1 masked to its neck, so the -- body walks and the head looks about; the right one starts as a ragdoll, is switched back to -- animation and eases from wherever it fell into Survey through a fade from the captured pose. local font = fontLoad("Singe/FreeSansBold.ttf", 28) local frames = 0 fontSelect(font) sceneEnable(true) sceneSetBackground(90, 110, 140, 255) sceneSetAmbient(90, 95, 110) local ground = materialNew() materialSetColor(ground, 110, 120, 100) materialSetRoughness(ground, 0.9) local plain = nodeNew() nodeSetMesh(plain, meshPlane(30, 30), ground) bodyNew(plain, BODY_STATIC, SHAPE_BOX, 30, 0.1, 30) nodeSetPosition(plain, 0, -0.05, 0) local foxModel = modelLoad("testScripts/Models/Fox.glb") local function fox(x) local node = modelInstance(foxModel) nodeSetScale(node, 0.02, 0.02, 0.02) nodeSetPosition(node, x, 0, 0) nodeSetRotation(node, 0, 60, 0) return node end local runner = fox(-3.2) animationPlay(runner, "Walk", true) local looker = fox(0) animationPlay(looker, "Walk", true) animationPlayLayer(looker, 1, "Survey", true, 1, 0.5) animationSetLayerMask(looker, 1, nodeFind("b_Neck_04", looker)) local faller = fox(3.2) animationPlay(faller, "Survey", true) ragdollNew(faller) ragdollActivate(faller) ragdollApplyImpulse(faller, "b_Spine02_03", 25, 20, -10) local sun = lightNew(LIGHT_DIRECTIONAL) nodeSetPosition(sun, 5, 10, 6) nodeLookAt(sun, 0, 0, 0) lightSetIntensity(sun, 2.5) lightSetShadow(sun, true) local camera = nodeNew() cameraSet(camera) cameraSetPerspective(40, 0.1, 100) nodeSetPosition(camera, 0, 2.6, 9) nodeLookAt(camera, 0, 0.8, 0) function onOverlayUpdate() frames = frames + 1 if frames == 70 then animationPlay(runner, "Run", true, 1, 1.0) end if frames == 110 then ragdollDeactivate(faller) animationPlay(faller, "Survey", true, 1, 1.2) end overlayClear() fontPrint(20, 20, string.format("Blending, frame %d runner time %.2f looker playing %s", frames, animationGetTime(runner), tostring(animationIsPlaying(looker)))) if frames == 40 or frames == 85 or frames == 130 or frames == 175 then singeScreenshot() end if frames == 180 then singeQuit() end end