Blitz3D+ Command Reference

AddAnimEvent entity,sequence,time#,name$

Parameters

entity - handle of an animated entity
sequence - animation sequence the event belongs to
time# - time within that sequence, in animation frames
name$ - name reported when the event fires

Description

Marks a point in an animation sequence that fires a named event when playback crosses it.

This is how you hang gameplay off animation without watching the clock yourself. Put an event called "footstep" at the frame where each foot lands, one called "hit" at the moment a sword connects, one called "eject" where a shell leaves a rifle - then pick them up with PollAnimEvent after UpdateWorld and play the sound, spawn the particles or run the damage check. The timing stays correct even when you change playback speed, because the event is tied to the animation rather than to a frame counter.

UpdateWorld queues an event every time playback passes its time, which means loops fire it once per lap, and reverse and ping-pong playback fire it on the way back too. Several events at exactly the same time are queued in the order you added them.

Events belong to a particular sequence, so a walk and a run each need their own footsteps. The time is in animation frames, the same units as AnimTime, and must fall inside the sequence; an out-of-range time, a non-finite time, an invalid sequence or an empty name all raise an error.

See also: PollAnimEvent, PendingAnimEvents, ClearAnimEvents, AnimTime, Animate.

Example

; AddAnimEvent Example
; --------------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

camera=CreateCamera()
PositionEntity camera,0,2,-6
RotateEntity camera,12,0,0

light=CreateLight()
RotateEntity light,45,45,0

; A grassy paddock for the fox to roam
ground=CreatePlane()
EntityTexture ground,LoadTexture("media/MossyGround.BMP")

; Load the rigged fox; it has the named clips "Survey", "Walk" and "Run"
fox=LoadAnimMesh("../../../samples/glTF/assets/Fox/Fox.glb")
If fox=0 Then RuntimeError "Could not load Fox.glb: "+ModelLoadError()

; Shrink the fox to game scale (the file is modelled about 100 units tall)
FitMesh fox,-0.8,0,-0.8,1.6,1.6,1.6,True

; AddAnimEvent places named events at ticks of the 43-tick walk cycle;
; UpdateWorld queues each name whenever playback crosses its tick
walk=FindAnimSeq(fox,"Walk")
AddAnimEvent fox,walk,10,"left footstep"
AddAnimEvent fox,walk,30,"right footstep"

CrossFadeAnim fox,walk,0,1

; A lamp that flashes whenever a footstep event fires
lamp=CreateSphere(8)
ScaleEntity lamp,0.3,0.3,0.3
PositionEntity lamp,-2,0.3,0
EntityFX lamp,1

last_event$="none yet"
flash=0

While Not KeyDown(1)

    UpdateWorld

    ; Poll the events queued by UpdateWorld
    While PendingAnimEvents(fox)>0
        last_event$=PollAnimEvent(fox)
        flash=10
    Wend

    If flash>0 Then flash=flash-1
    If flash>0 Then EntityColor lamp,255,220,60 Else EntityColor lamp,90,60,20

    ; 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,"Arrows: camera   Esc: exit"
    Text 0,20,"AddAnimEvent placed footstep events at ticks 10 and 30"
    Text 0,40,"Latest event: "+last_event$+"   AnimTime: "+AnimTime(fox)

    Flip

Wend

End

Index