I am having some issues with animations not running and with runtime errors on devices. I'll try to detail the issues and provide appropriate code. Maybe I am overlooking something simple that someone more familiar with spine will recognize.
Running in the Corona simulator, most animations run fine, including unit idle animations, etc. The only visible issue is that some attack animations simply do not play at all. There is inconsistency in this as the attack will play for one unit but not the other, even though they are loading the same spine json and visual assets. There are NO errors logged in the console or any indication that there is a problem. This is also a recent issue as at some point, all animations were running fine.
When running on android devices, there are many issues with the animations. Idle animations are seemingly random, some animate some don't. There is no consistency as to which work based on unit types, positions, etc even between turns. Some attachments do not appear at all or disappear after a non-idle animation. The non-animating attacks from the sim still do not animate. Reading the logs show this runtime error being spammed to the console:
I/Corona (20725): Runtime error
I/Corona (20725):
I/Corona (20725): stack traceback:
I/Corona (20725): [C]: in function 'removeSelf'
I/Corona (20725): ...-Brawl(default)\Monster-Brawl\spine-corona\spine.lua:110: in function 'updateWorldTransform'
I/Corona (20725): ...onster-Brawl(default)\Monster-Brawl\modules\unit.lua:264: in function 'updateAnim'
I/Corona (20725): ...Monster-Brawl(default)\Monster-Brawl\gamemanager.lua:671: in function <...Monster-Brawl(default)\Monster-Brawl\gamemanager.lua:665>
I/Corona (20725): ?: in function <?:218>
The code traces back to this line in spine.lua:
if image and image.attachment ~= attachment then
---
Attachment image has changed.
if self:modifyImage(image, attachment) then
image.lastR, image.lastA = nil, nil
image.attachment = attachment
else
---
If not modified, remove the image and it will be recreated.
image:removeSelf()
---
This is line 110************
images[slot] = nil
image = nil
end
end
My enterframe code calculates delta once, then calls this function for each existing unit:
function unit:updateAnim(delta)
self.sprite.animState:update(delta)
self.sprite.animState:apply(self.sprite)
self.sprite:updateWorldTransform()
end
Here is how the spines are being created within the unit module:
function unit.new(unitType, iff, position, hp, cd, eq)
local newUnit = {}
createUnitData(newUnit, unitType, iff, position, hp, eq)
newUnit.sprite = createUnitSpine(newUnit)
return setmetatable(newUnit, unit_mt)
end
The createUnitSpine function is local to the module. The relevant code portions look like:
local function createUnitSpine(newUnit)
local spine = require('spine-corona.spine')
local spinePath = 'assets/visual/animations/'..newUnit.model.spine..'/'
local skinPath = spinePath..newUnit.model.skin..'/'
local jsonSpine = spine.SkeletonJson.new()
jsonSpine.scale = 1
local skeletonData = jsonSpine:readSkeletonDataFile(spinePath..newUnit.model.spine..'.json')
local sprite = spine.Skeleton.new(skeletonData)
function sprite:createImage(attachment)
return display.newImageRect(skinPath..attachment.name..'.png', attachment.width, attachment.height)
end
sprite:setToSetupPose()
---
AnimationStateData defines crossfade durations between animations
sprite.animStateData = spine.AnimationStateData.new(skeletonData)
---
Set up to create transitions between ALL animations in table below
local animStates = {'idle','hurt','select','dead'}
local animTransTime = 0.3
---
common length for all transitions
for i=1,#animStates do
for j=1,#animStates do
sprite.animStateData:setMix(animStates[i], animStates[j], animTransTime)
end
sprite.animStateData:setMix(animStates[i], 'attack1', animTransTime)
sprite.animStateData:setMix(animStates[i], 'attack2', animTransTime)
sprite.animStateData:setMix(animStates[i], 'attack3', animTransTime)
sprite.animStateData:setMix(animStates[i], 'attack4', animTransTime)
end
---
AnimationState keeps queue of animations and applies via crossfading
sprite.animState = spine.AnimationState.new(sprite.animStateData)
sprite.animState:setAnimationByName(0,'idle', true)
return sprite
end
Does anything look out of sorts? Why am I not seeing any runtime errors in the simulator? Any help or advice is appreciated. Thanks.