• Editor
  • Suggestions: enable-disable constraints/sliders and Return keys

Great input @Paperbot, we really appreciate your ideas! Sorry for my delayed response, got hit with the man flu. 🤮

I wrote a bit about the slider slowdown in the issue Misaki linked above (fixed in 4.3.25-beta, available now). We put reasonable effort into the editor being efficient and occasionally we do testing with huge projects to see where further improvements can be made. For this, sliders are new and were doing work that could be avoided. Still a draw order timeline with 26,000 keys is relatively slow in the editor (27fps for me). Probably don't do that. 😉

The idea for "clear" keys is a good one! 4.3 might be a good time to get it in. We'll check how disruptive it will be to implement.

The idea for numbered animations for sliders is maybe a bit complex. We have considered allowing a slider's animation to be keyed. We even implemented it, but removed it. For sliders to work significant runtime changes were needed (that's why porting is taking a while) and this feature complicated that. The dust is mostly settled now, so maybe it could be revived. When a slider animation changes, the skeleton "update cache" has to be recomputed. That is relatively heavy, but could be OK if it doesn't happen very often (surely not 26,000 keys, right?!). The editor already does it every frame so the impact is only at runtime.

Anyway, once you can key a slider animation, then you can just use another slider and that gives you the numbered slider animations that you wanted. There is no problem that can't be solved by throwing sliders at it! 🛝

  • Paperbot ответили на это сообщение.
    Related Discussions
    ...

    Nate

    I appreciate the response.
    My suggestions (except "clear" keys) were made under the assumption inactive (mix 0) sliders and constraints were computationally significant outside editor use. I failed to consider this was unintentional and/or an editor side thing, I jumped the gun and took it as indication that 0 mix sliders were hogging resources in all cases. And yes, as you mentioned, similar results can be achieved through the use of sliders, given they don't passively tax resources, so 2/3 suggestions are somewhat redundant.

    About the 26,000 keys: I discovered this while attempting to make a "multidimensional array" draw order control for separate elements. This involves 350-400 draw order keys, nowhere near that amount, but this effect seems to be magnified either by slot count or perhaps the presence of other constraints (I'm using 1200+ of them in the project in question). So while it is a non factor for regular use, I guess it can become a problem for people getting extra creative with sliders, of which there is vast potential. On that note, thank you so much for implementing this, it's genius stuff, really, I keep finding and finding new slider uses for virtually everything I do.

    I'm scared of what a multidimensional array might mean! 😆 It is really cool seeing what people come up with, especially when it's not readily apparent even to us how they could have possibly done it.

    Spine is very efficient in general because it is written like a game rather than like a typical desktop app. That allows us to not worry about performance most of the time, as the performance we get without special acrobatics is acceptable for the majority of users. This is good because optimizations can greatly complicate development. The flip side is that Spine may not scale up to what it potentially could, if it really needed to.

    That said, if you run into a real world scenario where performance is an issue, please let us know and we may be able to improve it. There will always be limits that can be found with artificial scenarios, such as how many attachments can Spine handle before slowing down (IIRC 50-75k). As long as those are higher than any sane person would ever do, we're good. Eg, if you have 50k+ attachments you should probably be creating them at runtime with templates rather than rigging them all in Spine.

    You can check performance in Skeleton Viewer to see how it compares to the editor. Of course you shouldn't have to suffer through a 10 FPS editor even if it's OK at runtime.

    Thinking about "clear" keys, it would be pretty easy to make it a curve type. In other words, the transition between 2 keys could be set to stepped, linear, Bezier, or "clear" which would mean no change. For animations applied on top of others, this would allow the animations below to control the value. The downside is there is no transition. It would work like stepped: whatever value the animation was setting, suddenly the value from the animation below can be seen. That's OK for attachment visibility or anything else without transitions, but I expect people will want to transition smoothly to/from animations below.

    To do that and keep it a curve type, we could say all clear keys are also Bezier. That's a bit hacky though. It also means you'd have some useless Bezier handles:

    some keys > clear key > Bezier transition > clear key for the end of the transition > useless Bezier transition > clear key to start transition back > Bezier transition > some other keys

    Otherwise, if it's not just a curve type we'd need a sort of first class key value possible for every timeline, then you'd be able to use stepped, linear, or Bezier as normal.

    Or, we could make it a modifier on the curve type. So you still set stepped, linear, or Bezier but also whether it is clear. This works well with the many timelines that have curves. For the timelines that don't (attachment, draw order, event, inherit, physics reset, sequence), we'd need to do something else.

    • Paperbot ответили на это сообщение.
      • Изменено

      Nate
      Using curve types would be an ingenious way to integrate it, while also keeping the UI clean and easy to understand (no small thing).
      I also agree, as you mentioned, requiring different types of curves may prove more versatile.

      I'm unaware on how complicated/conflictive this implementation would be, but I think the best bang for the buck in terms of versatility of use would be to treat "clear keys" as an "intro and outro" special key though.
      For bone transforms, the key would functionally act as "0" on additive, and look as "0" position in the graph. On non-additive this would act as a "return" position over whatever is active before the animation.
      Goes without saying then this could then be set to stepped, linear, or Bezier (may want to lock the handles as horizontal? I don't know what a "clear 110% or -50% from clear to specific position would even play like). This also potentially solves the issue for attachments, inherit, draw order, sequence I think, or at least makes everything simpler to understand.

      Given "clear" does nothing if not used in conjunction with other keys within the animation, I don't think it would require buttons on the tree or anywhere else but the dopesheet, given it's only clearing a timeline for a single element within the animation it's set)

      Here's a mockup example:

      The clear key positions (1, 5) would always match the setup position. In additive this behaves exactly as "0" (sorry, base setup value, I don't know what to call it).
      In non-additive, 1 mixes into 2 (intro), and 4 mixes into 5 (outro).
      (perhaps clear key could contain values for next/before key to mix into them, since it's not exactly moving value to value? I don't know the specifics of how this works, apologies)

      It stands the key could be applied anywhere on the timeline, or turn a "0" key into a clear key. If the clear key is applied while on the same frame as an existing key not equal to "0", the button could be greyed out or return an invalid action error, rather than replace an existing key as "0".
      This goes for any other keys, including draw order, transforms, FFDs... Clear could always require the key to be "setup value" to avoid confusion.
      Another way to look at it is: clear key as a "setup value" regular key with an added special condition.

      Personally, I would find clearing attachments the most useful, but, I feel something like what I presented is a more versatile way to exploit it, since it has plenty of use for non-additive animations to gently mix into other active animations, a nice option to have.
      At the end of the day you're the one with all the backend know how and I don't wanna be presumptuous on what the best implementation method or application is. Last thing I want is to help send you down a rabbit hole that overcomplicates your work.

      No worries, it's helpful to think through all ideas. We have no problem discard those that are too hard. 😉

      I agree a button in the dopesheet and graph may be sufficient.

      After more thought, it seems hard to use the Bezier handles for the clear transition. The handles are in "value space" while the transition to or from clear is a percentage. Using the setup value as the clear value to define the transition could work, but feels a bit magical. A better way might be to have a separate timeline just for clear, though that has some complexities.

      I'm now thinking maybe stepped and linear could be enough. After all, those are the only options when mixing between animations with AnimationState. Maybe clear can even be just linear, if it simplifies things.

      Here's a proposal: any key can be marked as clear. The first clear key after a non-clear key is a linear transition to clear (fade out). Adjacent clear keys hold clear. The next non-clear key makes a linear transition to not clear (fade in). All keys work the same as normal -- you can still set values for clear keys, so you have the normal transition between key values and also fading in or out.

      This makes clear a sort of annotation on top of the regular key system. Storing which keys are clear is easy. The difficulty of this feature is mainly what it does to the timeline logic. The next step is adding it to one timeline type and seeing how gnarly it gets.

      • Paperbot ответили на это сообщение.
      • Paperbot оценил это.

        Nate
        That sounds functional enough. As I understand It's better to keep the UI as tidy as possible, as in the niche case where one really wanted to get bezier fade in or out it would be possible to get that by creating a slider and bezier on mix.
        And when you put it that way, it makes sense to apply it to keys, also potentially having Clear be able to "ride" along a potential bezier curve instead of just into a "flat" position. Feels like it would be easier to understand, in backend logic and for the user.

        Crossed fingers testing doesn't cause a cascade of issues

        We tried it out and I hoped to shoehorn it in with minimal changes, but ultimately it complicates the timelines a bit more than I like.

        The lack of clear keys can be worked around by using multiple animations. For example, an animation played on top of other animations that does some main action, then has a few animated parts lingering for a while could be 2 animations: 1 for the main part and 1 for the lingering part. 2 animations is a bit annoying to manage, but it's possible.

        There's also another way that's pretty flexible: use a slider for the part that needs to be clear. When a slider's mix is 0, its animation isn't applied at all. That means what it affects can be either keyed or clear at any time. This may come close to "playing" an animation be keying the slider frame, which so far I've been recommending against, but it could do the job. One caveat is all animations on all tracks are applied, then sliders and other constraints are applied. That means the slider animation is always on top of all animations.

        Given those 3 things I think it's better not to implement clear keys. It's a neat feature but the need doesn't come up super often, has workarounds, and is a bit involved to implement. It was interesting to think through and was worth a look!

        • Paperbot ответили на это сообщение.
        • Paperbot оценил это.

          Nate
          Well that's unfortunate to hear but probably for the best.
          In my case, sliders is probably not the best solution since I have a lot of variability going on in what I'm doing. To give you one example, I have about 30+ hand "states" (unique attachments) for each arm, which are used on base and overlaid animations. Creating 60 sliders to be able to clear the attachment mid animation is probably not the most elegant way to go about it.
          Still, I fully understand this would be a rare niche use of what Spine usually does and it doesn't warrant burdening the rest of the program for what amounts to quality of life feature rarely used. Besides, I already have workaround ways to handle these issues in place (clone attachments into different slot, hide main hand instead of disabling attachment). As you implied, with sliders this falls into ease of use and smoothing workflow, not functionality.

          Thanks for the attention and please keep doing what you're doing, these new tools are amazing

          • Nate оценил это.

          Maybe you could use one slider with each attachment keyed on a different frame? Than you'd use the slider to choose which attachment is visible, with 0 mix to clear.

          • Paperbot ответили на это сообщение.
          • Paperbot оценил это.

            Nate
            You're right, actually. I've been using that method for other stuff lol don't know how I missed it
            Thanks!

            • Nate оценил это.

            Nate
            Apologies for not letting this solved thread die.
            I just thought I'd bring something into consideration: Using a slider as an override for attachments has one key limitation (predictable behavior as has been thus far, I don't think it's a bug). Any FFDs applied to the swapped slider attachment will be ignored, as this is akin to applying an FFD before an animation which activates the FFD deformed attachment.
            Meaning as is, slider attachments cannot use FFDs unless it's contained within the slider itself, or affected by sliders below in the constraint list. Or, unless the attachment itself was already active.

            This is exactly how its meant to work, am I correct?

            I believe that is working correctly. A deform (FFD) can only be applied to 1) the mesh the deform was keyed for, or 2) any linked meshes for that mesh that have "inherit timelines" checked.

            As always, we recommend not using deform keys as much as possible:
            https://esotericsoftware.com/spine-keys#Deform-keys
            Use bone weights to deform meshes, it's better!