So wait you never turn off the additive you just have a setup animation that keeps resetting stuff on a previous track, and additive sounds like it's universal for all tracks not just a select few tracks like it's represented in spine? Why does this work so differently to how it functions in the editor, I feel it's setting up a completely different expectation for a lot of users. I get runtime is very different from what an editor can show you but this seems needlessly complicated for what I'm trying to do. I tried putting my setup/reset animation on track 0 (though it's a little more complicated with my setup since I have two setup poses for the front and back view of my character) with everything else on top but I still had the same scaling issue and it wasn't showing any sign of the actual recoil animations even with the additive infinity scaling. Maybe I can key more things on my setup/reset animations but even then it seems like the recoil animations aren't even going through at all. Do you mind if I send my project files over or should I just scrap having recoil animations through spine since this seems like a really unreliable process, especially if my rig/animation setup gets even more complicated later on.
[Godot] Additive Mix Blending Bug After Track Entries Completed
Alyria you never turn off the additive
If you turned it off, you would get the pose from the animation rather than having it added to the current pose.
Alyria additive sounds like it's universal for all tracks not just a select few tracks like it's represented in spine
There's nothing universal about it. Only a TrackEntry with MixBlend add will add the animation values to the current pose.
Alyria Why does this work so differently to how it functions in the editor
The editor uses setToSetupPose
each frame.
Alyria this seems needlessly complicated for what I'm trying to do
Calling setToSetupPose
each frame is not complicated. Resetting with an animation is a bit more effort.
Alyria but I still had the same scaling issue
If you are still seeing the scale grow every frame, then you are definitely not resetting the scale each frame.
Alyria Do you mind if I send my project files over
We would look at them if it would help, but I don't think it would in this case. The problem is that you are not resetting the scale that is being added to each frame by the additive animations. Get it working with setToSetupPose
before using an animation to reset.
Alright so after a two week break from game dev I came back to test some more of my code and try to get to the bottom of this (sorry about my frustrations the other week I was rushing myself for no reason and got really impatient). After further testing I was able to stop the infinite scaling/additive from being applied every frame by putting setToSetupPose outside the IF statement(in PhysicsProcess) like you suggested. I had already done this earlier in the thread but I probably should have specified in my previous post that while it fixed the scaling issue it brought a few new problems with it as it wasn't a perfect solution.
Because this is a recoil animation, I need this animation to be over very quickly, which means no mixing when adding/setting the animation and only a very small amount of mixing when mixing out (currently I'm mixing out using two empty animation tracks. However when I have the mixduration (or delay, they both seem to have the same problem) on the Add/SetEmptyAnimation set to a very small number say below 0.5, the animation seems to rapidly transition between the two states (seems like every frame) and it seems to do this for about half second before resetting to normal. I could try using godot's timers instead of mixduration/delay since it doesn't seem to be working properly when both the add recoil/add empty track logic is in the same IF statement. Is there something else I should be doing for mixing out the recoil in this situation?
The second problem is that my aiming logic is completely invalidated by the setToSetupPose being processed every frame, which is uh, kinda a big problem for a twin stick shooter. The projectiles are only being shot from 1 angle (which is flipped if you're looking left). I tried using both a SpineSlotNode and SpineBoneNode (they both work the same for aiming projectiles since you're simply taking their rotation and position) and they both produce the same result. I would think the aiming be limited to at least 2 angles depending on if you're looking down or up (front and back view have different aiming animations). Any ideas how both of these problems might be alleviated while still having the ability to have additive recoil animations?
This is what I have for code atm
and here's a small clip of what's happening (the rapid switching is a lot less pronounced in the clip probably because of the low frame rate the vid is set to)
Alyria when I have the mixduration (or delay, they both seem to have the same problem) on the Add/SetEmptyAnimation set to a very small number say below 0.5, the animation seems to rapidly transition between the two states (seems like every frame) and it seems to do this for about half second before resetting to normal.
I'm not sure what is going on here. The video doesn't help because I'm not familiar with your project or how it is supposed to behave. It looks good to me! It seems like when you shoot twice, two recoil animations happen.
If there is a problem with the recoil animation, you'd probably need to create a simple app that ONLY shows this problem so we can take a look. Please don't send an entire app. Make an SSCCE.
Alyria The second problem is that my aiming logic is completely invalidated by the setToSetupPose being processed every frame
Calling setToSetupPose
should not wreck your aiming. Every frame, after you setToSetupPose
and apply your animations, then you adjust your bones for aiming.
I can send you my project files, like I said the rapid switching is harder to see on the vid but it also illustrates that the aiming is malfunctioning.
Nate Every frame, after you setToSetupPose and apply your animations, then you adjust your bones for aiming.
I'm not totally sure what you're even saying here, I tried putting setToSetupPose higher in PhysicsProcess() (above the SetAnimation for my aiming animation) but it doesn't seem like it's changing anything. I have 1 frame aiming animations where the weapon bones are rotated based on the position of an IK constraint bone that's being driven by my mouse position in godot.
- Изменено
If it's necessary to send us a project showing the problem, you need to make a simple project that only shows the problem and doesn't have anything else. If you send your whole project, we won't have time to look at it. That said, you can send it here: contact@esotericsoftware.com
Every frame:
setToSetupPose
.- Move your IK target bone to the mouse position.
- Apply animations (eg call AnimationState
apply
).
If calling setToSetupPose
messes up your aiming, it's because you are doing 2 and then 1.
Alyria I tried putting setToSetupPose higher in PhysicsProcess() (above the SetAnimation for my aiming animation)
This is confusing because you should never be calling SetAnimation
every frame. You set and add animations only when events occur, like the player jumps or shoots.
sent my project files over, I was able to fix the weird stuttering on the recoil by using a different method for the input singleton, but I'm still having trouble with the aiming being broken.
You sent a 226MB ZIP file. Sorry, but it is not reasonable to for us to debug your entire application.
Nate This is confusing because you should never be calling SetAnimation every frame. You set and add animations only when events occur, like the player jumps or shoots.
for my application that's too limiting as I need the player to be constantly updating their animation based on the position of their mouse cursor (front and back views are different animations). I changed how the SetAnimation functions as it checks to see if the same animation is already playing and if it is it won't be reapplied.
Nate EDIT: I see you sent a 226MB ZIP file. It is not reasonable to for us to debug your entire application.
oh wait sorry, I just realized I've been sending my export templates for no reason, I thought the mono/godot files we're taking up most of the space.
Alyria for my application that's too limiting
It is never the right solution to call set or add animation every frame. It doesn't make logical sense, so however you think it works must be flawed. After setting an animation, it is applied every frame from then on, without you needing to set it again.
Alyria I changed how the SetAnimation functions as it checks to see if the same animation is already playing and if it is it won't be reapplied.
That is a reasonable way to do it. It sounds like that solves your recoil problem and my post above solves your aiming problem.
Nate my post above solves your aiming problem.
I don't see how it does, I already said that moving the setToSetupPose method higher in Process() doesn't seem to do anything even though all my aiming logic is written after it. Admittedly I don't have code that says to move the IK bone to my mouse position in that script as I accomplished that in the editor with the SpineBoneNode and it's drive property as instructed in spine's tutorial. Should I do that through code instead then as it seems to be processed first if the problem you're describing is true?
The order of processing when using SpineBoneNode
can't be guaranteed. For your case, where you move an IK target AND also apply additive blending, you will have to implement the entire logic of moving the IK target in your process()
method.
Alright so I finally seemed to have gotten everything working but was wondering if this is the best solution. Currently I have a Node2D that's dedicated to following my mouse position that I then take the transform of and set it to my specific IK bone. Using SetX/Y or SetWorldX/Y seems to cause some problems, I'm guessing because of how godot's coordinates work where -Y is up and Y is down. The runtimes doc/api is a little confusing with all the different properties for specific bones (in godot's case set methods) so not sure if I could be doing something better.
Here's what I have for my code currently
SetGlobalTransform()
is exactly what you should use. Setting x/y on the bone is also possible, but as you found out much more involved.
Glad you figured it out!