Thank you for long explanation. I will try to sum up proposed approaches. And may be explain why they do not fit me. This is just to make sure I totally understood proposed approached.
1.
Approach one: implement idle animation where run ends. We implement story, so we will have multiple actions, after which we need idle. I call it run for simplicity. But across story, skeleton will run a lot and stops in different places. So end of each action animation might ends in different places, and idle is a way to keep skeleton in place while we playing sound till end. (we can't guarantee timing of sounds, localizations are difficult)
2.
Approach 2: move skeleton after animation This approach would be the easiest... if only our character didn't have more elements in skeleton. So items, which in skeleton hands, he sometime drops. And if I move root, it will move other elements which are on the ground now(breaks animations....). This is how our animator did it now. Because he need move items with skeleton and some of them need to be between hands of skeleton
I see possible adoption here. we have in skeleton parent bone for character itself. So all additions are not part of it. I assume I can create programatically animation in runtime, add to this
characterParent
bone on other track and play in parallel to idle. So idle will play together with those animation, which will move character where we need it to be. Pleasse let me know, if this make sense, I will try to implement it now.
Other possible adoption here is move everything extra from skeleton and use IK to connect 2 skeletons. Fiew issues here. I don't know - can we connect 2 skeletons with IK? Other issue is how put elements from other skeleton between characters hands in draw order
3.
Option 3: mixBlend
: I might got the idea, but some terms make me think that I again have some mistunderstanding.
My assumption of how 2 track system works - if you have 2 animations in parallel, they both apply effect on skeleton at the same time. So, for example, with facial animation. We have "idle" animation and I can make. it "sad-idle" by adding "idle" on track 0 and "sad" to track 1. And if idle and sad do not touch same bone, things will work as intended.
Here I assume
mixBlend
is intended to help solve how we handle when 2 tracks effect same bone at the same time.
I honestly don't think it help me in my case. As if "run" and "idle" don't finish/start with same pose, we will have strange pose of idle applyed on final frame of "run". Like example with rised hands on last frame of "run". Which is bug in animation now, which helped me catch that animation didn't switch smoothly, later end of "run" and start of "idle" will have same pose or almost same(not position in screen). Thats why I like mixDuration, it helps fix situation with "almost" same poses.
Alternatively here I might confuse lower tracks, aka track 0, 1, 2 and lower track animations, aka animation in the same track but played before.
4.
Option 4: Ghosting offset This is amazing option for game, for sure. As we do story telling, for us simpler if animator responsible for everything or almost everything. So I don't need to think on movement in every scene. We even consider options on how implement camera on his end, so I will just follow it during rendering.
5.
Option 5: root motion. Not exactly match what I want, as I can't use root or whole skeleton as I explained, but this is what I will try today, create animation on one bone, which is bone to which whole movement applied. I will try to read docs, because I need find way to identify translation of bone in end of "run" and add same translation in new created animation and play it parallel to "idle".
6.
Options 6: Hold previous To be honest I do not undestand answer. It totally works in my case, where I use it when add idle. And it keep changes in position not only during animation mix, but also during whole idle in loop. And I don't understand why this is not what I want. Will it stop working if I add third animation? Will it drop changes from first after adding third? You also was against usage of this bool in linked post, but looks like there it was also the thing, which will fix their issue.
This is what documentation says:
Snapping will occur if holdPrevious is true and this animation does not key all the same properties as the previous animation.
But in my case "idle" do not override(not keyed) translation for
characterParent
bone and yet, charater stays on place. This is what worry me, as it might looks like a bug in current runtime and soon will be fixed, which breaks my code. Or may be, you need change documentation, saying that not keyed changes from first animation will stay in place until keyed by second or any next animations. Does it make sense?
---
So I did try to implement extra animation on other track, which will move skeleton to needed position to keep it there for idle. And looks like it works.
What I did:
1. Find bone with needed name in skeleton. I assume that bone index won't be changed during lifetime.
2.
spSkeletonData_findAnimation
+
spAnimation_apply
to find bone position in the end of animation.
3. make a diff between final position in animation and spBone.data.x, to know actual translation
4. Crearte animation in runtime, here is code, will do my best with C, even tho my code is in swift
spTranslateTimeline *pTranslateTimeline = spTranslateTimeline_create(2, 0, moveBoneIndex)
spTranslateTimeline_setFrame(pTranslateTimeline, 0, 0, position.x, position.y)
spTranslateTimeline_setFrame(pTranslateTimeline, 1, duration, position.x, position.y)
spTimelineArray *pTimelineArray = spTimelineArray_create(1)
spTimelineArray_add(pTimelineArray, pTranslateTimeline)
spAnimation_create("tmp_animation", pTimelineArray, duration)
spAnimationState_addAnimation(pAnimationState, 1, pAnimation, 1, delay)
With this code It looks like it works for me. All I need is just clear track at index 1 before playing next scene.
Also, I checked unity code, which you linked. And as I understood you looking for shift between time A and B. This kinda clear. But I didn't understand what you do with this shift after that? I always can add it to shader and move every vertex... but I would prefer spine runtime to do all of this for me. Thats why for now animation looks like a working solution.
Please, let me know, if this make sense and may be I can improve or I missed smth.