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

Some context:
I'm working on a rather extensive experimental thing with 1000+ slots, constraints and bones. It's a character mixer with a vast amount of interchangeable parts and a lot of precise targeted stuff intended for mutilayered animations (only some parts active at a time).
I understand something this size is a rather specific and an atypical use of Spine, but there are some things that would really have a massive impact on medium-large projects like mine, even though I feel they're not the software's target.

  1. Enable/Disable switch for constraints-slider constraints
    Much like attachments work, this would deactivate them as if they're hidden, but able to be keyed into animations to only use when required.
    This is almost purely for performance reasons, since constraints need to be always active, and it could be useful to have in general given the new complexity layer the beta has brought out.
    For example, I recently attempted to make a draw order multidimensional array built into the rig (partly for style points). Setting up a bone's X-Y position to control 2 separate element's draw order independently, which position corresponds to a specific draw order combination. Then I expanded this into several of these grids to add a 3rd independent element.
    It's cool and it works, but sliders always needing to be monitored every frame, and being 1000+ slots on 300-400 draw order keys running at the same time... Performance was, predictably, destroyed .
    Cool but expensive stuff like this could be given more room to breathe if inactive sliders could be disabled when not in use.
  1. Fallback/Return keys
    When layering animations on top of one another, it would be useful to return them to a state equivalent to where the key was never in use. This works for transforms when using an animation as additive and set to base value, but it will not for non-additive, or when applied to attachments.
    For example, animation1 with attachment A or animation2 with attachment B may be active. If animation 3 is overlaid and changes attachment to C, it is now impossible to return to the previous A/B without disabling the animation. Perhaps animation 3 contains lingering motion of other parts before it blends back. This applies to draw order as well, and could be useful for mixing back any element in non-additive animations.
  1. Animation pointing sliders
    This one's a bit out there, but this could also complement the layered stuff sliders bring to the table. Essentially the same thing as sliders, but setting up animations (in a folder, for example) to be pointed at independently on a numbered basis. This index can then be modified by another animation (as frames work).
    Application example: Putting several expressions in a folder, an active control animation dictating the "frame", and a general body animation containing a keyed mix, that would mix in any selected expression.
    This can be done with sliders right now if static expressions are put into the same animation, the key difference is on the animation being pointed at, meaning it wouldn't need to be static, nor it would need everything else to be active at the same time.
    This may be better left handled by engine, but it may also be useful to have integrated for certain cases.

Thank you for the continuous support and attention

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

    Paperbot Thank you for your suggestion! I would like to quickly correct one point that I think you may have misunderstood:

    since constraints need to be always active, and it could be useful to have in general given the new complexity layer the beta has brought out.

    No, constraints are not always active. Constraints can be disabled by setting the mix to 0 or by including them in a skin and then disapplying that skin. For more information on how to add constraints to a skin, refer to the following section of the Spine User Guide:
    https://esotericsoftware.com/spine-skins#Skin-constraints


    I am still reading through the other points and need more time to imagine actual use cases, so I will respond with additional comments later.

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

      Paperbot

      1. Fallback/Return keys

      Based on the example you provided, it seems like the issue could potentially be resolved by separating the animations and consolidating the ones that manage the same attachments onto a single track. For instance, it’s common practice to dedicate specific tracks to different parts of a character — such as using track 2 for eye animations and track 3 for mouth animations. That’s why I had trouble understanding why this approach wouldn’t work in your case.

      Additionally, methods like setEmptyAnimation or setToSetupPose can reset the pose to the setup pose from the previous animations when needed at runtime.

      To better understand your specific use case and why this functionality might be necessary, it would be helpful if you could create a small sample project demonstrating the issue and send it to us via email: contact@esotericsoftware.com


      1. Animation pointing sliders

      This proposal is certainly creative, but I have some concerns from a practical standpoint. Specifically, I’m worried that introducing a feature where a slider indirectly selects an animation by index would add a layer of indirection that could be difficult to manage in larger projects.

      Currently, Spine doesn’t provide an easy way to see what value is keyed on a slider without selecting the keyframe and manually inspecting its value. That means if a slider is used to determine which animation is active, it could become difficult to understand why something is happening just by looking at the timeline.

      In contrast, managing animations via AnimationState at runtime keeps the animation flow more transparent: you can clearly see which animations are playing on which tracks, and the control logic remains centralized within the engine, where dependencies are easier to manage.

      You mentioned that it might be better handled on the engine side, and I agree. If anything, I think it would be helpful if the Spine Editor's preview tools allowed for more advanced testing — such as playing back individual tracks at specific times. But embedding this kind of logic directly into animations could lead to confusion, especially when trying to maintain or debug complex setups.


      I don’t mean to dismiss your idea at all, but from our perspective, we try to prioritize features that will be broadly useful across as many use cases as possible. We're still not entirely sure whether the feature you're suggesting would benefit a large number of users, so if you have any additional context or supporting information, we’d be happy to hear it.

      Misaki

      Thanks for your reply.
      Skins is actually a great suggestion that does circumvent the issue! I am a bit embarrassed I didn't consider it, thank you.

      As for 0 mix constraints being disabled:
      I can at least confirm this is the case for slider constraints, but not so much for transform constraints, I just assumed perhaps incorrectly they're subject to the same behavior. Maybe they work differently and transform constraints are indeed ignored at mix 0.

      Please try replicating the following:
      .open snowglobe-pro, or preferably a project with a higher slot count (I believe this exacerbates the issue)
      .create a test animation
      .key draw order and copypaste an absurd amount of times, for me 26.000 on animation did the trick

      .turn it into a slider and set mix to 0

      .if you're not getting a massive fps drop, then duplicate the animation and give it another slider, mix to 0

      .once your Spine is all laggy, hide the constraint/s and it'll go back to running smoothly

      This is what led me to believe that, while 0 mix does not affect transform values, it is not truly inactive, as it's demonstrably still siphoning resources. I simply assumed while 0 mix is practically disabled in terms on behavior it needs to remain active in case mix changes at any point.
      My suggestions are possible ideas to circumvent this issue (except 2, that is a separate suggestion I decided to toss in).

      If this is not intended behavior, scratch all of this and I apologize for not approaching it in a different way.

      .

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

        Ah, sorry, skins is the only thing I don't normally use at all. I thought they could be keyed into animations. I'm afraid their effect is only as good as hiding/disabling manually.

        Paperbot Thank you for providing the steps to reproduce the issue!
        After creating an animation slider that caused such drops in FPS, I confirmed that, even when the slider's mix value is set to 0, unrelated animations and the editor itself become laggy. This is indeed an issue that needs to be addressed. I will create an issue ticket for this.

        Regarding skins, I would like to add one point:
        There is an important distinction between disabling constraints via skins and disabling them by setting them inactive in the tree view—particularly in terms of whether they can actually be made inactive at runtime.
        Disabling constraints using the visibility dots in the tree view is intended only for preview purposes within the Spine Editor and does not affect the exported data.
        While skins themselves cannot be keyed in animations, they can be set or removed at runtime via script. For example, you can set event keys during an animation and then use those event keys to change the skins. Skins are an effective means of disabling and enabling many constraints instantly, without requiring smooth transitions.

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

          Misaki
          I see now. I simply assumed it was intended behavior, my mistake.
          Thank you also for the tips, all very useful. You've been more than helpful

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

            Paperbot I'm glad to hear that it was helpful!

            I have created an issue ticket to fix the problem with the slider affecting the editor's performance:
            EsotericSoftware/spine-editor892
            You can subscribe to this issue ticket to receive notifications when there is any progress on this issue.

            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 ответили на это сообщение.

              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?