• Runtimes
  • Animation layering doesn't work in Corona

Hello,

I'd like to use 'animation layering' feature, but it seems it doesn't work.
I've attached example. It's simplified Spineboy example with 2 simple animations of two boxes: 1) 'breathing' boxes 2) 'head' movement. When I play both animations on different tracks I expect boxes 'breath' and move 'head' at the same time, as it is in Spine Preview. (Please check my Spine Preview video here https://www.dropbox.com/s/megv124ayswthwn/breathing-boxes-preview.mov?dl=0 ) But only one animation is played. I've attached all source files.

Corona version: 2018.3326 (2018.6.25)
spine-lua version: May 1, 2019
spine-corona version: May 1, 2019

Runtime:addEventListener("key", function(event)
   if event.phase == "down" and event.keyName == '1' then
      print('animation 1')
      character.state:setAnimationByName(0, animation1, true)
   end

   if event.phase == "down" and event.keyName == '2' then
      print('animation 2')
      character.state:setAnimationByName(0, animation2, true)
   end

   if event.phase == "down" and event.keyName == '3' then
      print('animation layering')
      character.state:setAnimationByName(0, animation1, true)
      character.state:setAnimationByName(1, animation2, true)
   end
   return false
end)
Related Discussions
...
  • Изменено
месяц спустя

Finally had time to look into this. Lua 1-based indexing strikes again. If you queue the animations in track 1 and 2 instead of track 0 and 1, the layering works as intended. This is now fixed in the 3.8 and 3.9-beta branches. Thank you for the great reproduction sample!

2 месяца спустя

Hello,
there is still an issue with this bug. I looked into "AnimationState.lua" file and came up with the following.

Firstly in "_animationsChanged" function. You changed:

for i,  entry in pairs(self.tracks) do

to:

while i <= numTracks do
   current = tracks[i]

but you still try to mix with "entry", which was renamed to "current":

if entry then
   while entry.mixingFrom do
      entry = entry.mixingFrom
   end
   repeat
      if (entry.mixingTo == nil or entry.mixBlend ~= MixBlend.add) then
         self:computeHold(entry)
      end
      entry = entry.mixingTo
   until (entry == nil)
end

And second one - "#tracks" only works if there are no empty tracks.
So lets say that we have multiple tracks: one for original animation, one for sitting (for legs) and one for face. Not all tracks are active at all times. If he is standing then we use original animation on track 1 and face on track 3. Because track 2 is empty "#tracks" will return 1 so it will also skip track 3.
This returns the correct length of tracks array:

local function getNumTracks(tracks)
   local numTracks = 0
   if tracks then
      for i, track in pairs(tracks) do
         if i > numTracks then
            numTracks = i
         end
      end
   end
   return numTracks
end
local numTracks = getNumTracks(tracks)

Everything has its pros and cons 🙂

Yes it's a shame, but at least I don't think that people use a large number of tracks which means that those iteractions will be very small and fast.

месяц спустя

This has been fixed in the 3.8 and 3.9-beta branches. Thanks for reporting!