The way we did it was:
- Manually assign frames to each animation.
- Use the model.play_anim() callback to trigger the next animation with an offset based on the number of frames.
Here is the rough and ready module that might help:
local M = {}
local ANIMATIONS_FRAME_COUNT = {
["idle"] = 61,
["reveal_intro"] = 31,
["reveal_intro_random"] = 90,
["reveal_waiting_loop"] = 31,
["reveal_jump"] = 61,
["reveal_end_loop"] = 61,
["ui_select"] = 30,
["ui_celebration"] = 45,
["inside_cannon"] = 91,
["flying_fast"] = 16,
["flying_slow"] = 16,
["swinging"] = 16,
["scared"] = 16,
["collision"] = 8,
["rolling"] = 4,
["celebration"] = 4,
}
local FPS = 60
local function get_offset(anim_id)
local frame_count = ANIMATIONS_FRAME_COUNT[anim_id]
local offset = 1/frame_count
return offset
end
function M.play_anim(url, anim_id, loop, blend_duration, cb)
local playback_rate = 1
local offset = get_offset(anim_id)
model.play_anim(url, anim_id, go.PLAYBACK_ONCE_FORWARD, {playback_rate=playback_rate, blend_duration=blend_duration, offset=offset}, function()
if loop then
M.play_anim(url, anim_id, loop, blend_duration)
else
if cb then
cb()
end
end
end)
end
return M
The main downside of this is that the frames of each animation has to be defined manually. We couldn’t find a way around this, because there is no way to get the total frame count from a model at runtime (or at least there wasn’t when we implemented this!).