So, really struggling here and could use some guidance. I just need to know the most basic method to get an animation on screen using Spine.
-- Require in the spine manager local spine = require ("spine-corona.spine") -- Extract animation data from Json -- Assume it's in a folder called "anim" and is named "skeleton.json" local json = spine.SkeletonJson.new() local data = json:readSkeletonDataFile("anim/skeleton.json") -- Make the skeleton using this data local char = spine.Skeleton.new( data ) -- Fetch the idle animation local idle = data:findAnimation( "idle" ) -- Overwrite how spine creates bone animations. -- Assume seperate images; no imageSheets. function char:createImage(attachment) return display.newImage("anim/"..attachment.name..".png") end -- Set the animation state -- If I remove this line, Corona loads with no error messages, -- but there is no character on-screen. idle.apply( char, nil, true)
Unfortunately, idle.apply complains that char (the skeleton) is nil. (It’s not - a print statement confirms it.) However, looking at the animationState code, it’s looking for “skeleton.skeletonData”, which doesn’t seem to exist.
Where am I going wrong? The esoteric sample code is nice but I don’t have animations to blend together. Just a single skeleton with a single animation to play.
I’m not sure this will solve the problem but apply should be called on the animation so it should be idle : apply(char, time, true). This leads me to believe that the idle variable is nil in the example.
You will also need to execute apply in a loop which increments a timer so that the animation can change based on the time change and then call skeleton:updateWorldTransform() afterwards to draw the change in animation. This is typically a runtime listener that gets executed on the “enterframe” event.
idle is not nil; not only is there no error on finding the animation, but it shows up (properly) as a table if you use a print statement.
If I apply an actual number to the time variable (ie: 1000) Animation.lua reports an error with ipairs() on line 49. If I move the apply command to a Runtime loop (ie: the one shown in the sample code provided by Esoteric) the same error occurs.
Did using : instead of . provide any useful results at least? :P
I’m not sure if it’s necessary but I also run skeleton:setToSetupPose() before doing anything else with animations for example (just because it was done in the spine example). It might be the setup that is needed.
I think everyone does that It’s usually the first thing I check for when I get an error that a variable that I know has a value is reported of having a nil value.
I think calling skeleton:setToSetupPose() should initialize the bone fields including rotation. It should be called towards the end of the setup code and definitely before the animation is applied.
Reaver, you’re absolutely right - setToSetupPose() does add those values. Crazy that it’s not just added while making the skeleton, but okay.
So now the project loads without errors…but there is nothing on-screen. (I know from experience that if I feed the wrong path/filename to :createImage() that I would get an error, so it’s finding the right assets.) I have the Runtime loop running like this:
local lastTime = 0 local animationTime = 0 Runtime:addEventListener("enterFrame", function (event) -- Compute time in seconds since last frame. local currentTime = event.time / 1000 local delta = currentTime - lastTime lastTime = currentTime -- Update the state with the delta time, apply it, and update the world transforms. idle:apply( char, delta, true ) char:updateWorldTransform() end)
That gets my character visible! The only problem? There’s no animation at all (despite the Runtime listener). So it seems that the code above (previous post) is not enough to animate?
Nice. I think you might want to have an animationTime variable that you add the delta value to
local animationTime = 0
then in render loop:
animationTIme = animationTime + delta
idle:apply(char, animationTime, true)
Right now if delta is roughly the same value each frame the animation will be set to the same state each time the apply is called. Apply sets the skeleton rig to a state based on the time. If the time is the same each time apply is called the skeleton will be set to the same pose.
I’m not sure this will solve the problem but apply should be called on the animation so it should be idle : apply(char, time, true). This leads me to believe that the idle variable is nil in the example.
You will also need to execute apply in a loop which increments a timer so that the animation can change based on the time change and then call skeleton:updateWorldTransform() afterwards to draw the change in animation. This is typically a runtime listener that gets executed on the “enterframe” event.
idle is not nil; not only is there no error on finding the animation, but it shows up (properly) as a table if you use a print statement.
If I apply an actual number to the time variable (ie: 1000) Animation.lua reports an error with ipairs() on line 49. If I move the apply command to a Runtime loop (ie: the one shown in the sample code provided by Esoteric) the same error occurs.
Did using : instead of . provide any useful results at least? :P
I’m not sure if it’s necessary but I also run skeleton:setToSetupPose() before doing anything else with animations for example (just because it was done in the spine example). It might be the setup that is needed.
I think everyone does that It’s usually the first thing I check for when I get an error that a variable that I know has a value is reported of having a nil value.
I think calling skeleton:setToSetupPose() should initialize the bone fields including rotation. It should be called towards the end of the setup code and definitely before the animation is applied.
Reaver, you’re absolutely right - setToSetupPose() does add those values. Crazy that it’s not just added while making the skeleton, but okay.
So now the project loads without errors…but there is nothing on-screen. (I know from experience that if I feed the wrong path/filename to :createImage() that I would get an error, so it’s finding the right assets.) I have the Runtime loop running like this:
local lastTime = 0 local animationTime = 0 Runtime:addEventListener("enterFrame", function (event) -- Compute time in seconds since last frame. local currentTime = event.time / 1000 local delta = currentTime - lastTime lastTime = currentTime -- Update the state with the delta time, apply it, and update the world transforms. idle:apply( char, delta, true ) char:updateWorldTransform() end)
That gets my character visible! The only problem? There’s no animation at all (despite the Runtime listener). So it seems that the code above (previous post) is not enough to animate?