Hello there! I want to create a tool with working animations, however I have run into some issues.
On my screen, when I equip a tool, it works fine. However, when another person equips the tool, their animations appear buggy/glitchy on my side.
is a video of what it looks like. At the start I test my character’s animations and they work flawlessly, and when I test the animation on another account, from the perspective of my first account, they glitch quite a bit.
In my code, when the tool is equipped, I basically run this function with the names of two animations, that are played one after another, and then a third animation to act as an idle animation, that is looped and played after the second one.
function play2(anim, anim2, idleanim)
if not active then return end
local t1 = tracks[anim]
local t2 = tracks[anim2]
local t3 = tracks[idleanim]
if not t1 or not t2 or not t3 then return end
activeAnim = true
t1:Play()
t1.Stopped:Wait()
if active then
t2:Play()
else
return
end
t2.Stopped:Wait()
if active then
t3:Play()
else
return
end
current = idleanim
activeAnim = false
end
There is noticeable glitching when I switch from one animation to the next. What can I do to fix this?
I looked on the Developer Hub and have not found a solution. I have tried to fix this issue with different ways and none of them have been successful so far.
I can’t offer an exact rationale for this behavior, but I’ll give my best guess for a lead.
Someone who is more knowledgeable can correct me and I’ll redact this post immediately if I’m just completely off the rails.
I would imagine it has to do with the structure of the network, and Roblox’s complex logic to smoothly interpolate the “best guess” position of other clients at all times.
We cannot see in “real time” on the internet due to latency. When Client A runs an animation, Client A must tell the server, and then the server must tell Client B about it. Client B will inevitably be running the animation at a later time than Client A is running it because the information has traveled so far. Possibly on the order of 300ms+.
When Client A switches to another animation, the position of Client A’s limbs will be interpolated to reach the first frame of the new animation. Client B will be interpolating those limbs from a different location, due to the first animation playing later for Client B, so the second animation is staggered. Since interpolation of limbs between animations always takes the path of least resistance, we see the musket flail wildly as the wrist rotates from an earlier position according to Client B.
But again, this is only my best guess. I’m hoping someone will blow my theory out of the water because otherwise this seems very difficult to work around.
I know the Animation Editor has a “Constant” easing style that removes the interpolation between keyframes, but I don’t think that’s exactly what you need.
The third one is an “idle” animation, so it just continually loops the same keyframe that you see in the second image. The idea is to have a lot of animations start or end at the keyframe shown by the first image, so that they may be connected via the pose the character will make.
Since I am using multiple animation tracks, I don’t think that easing styles will help me, but thanks for showing me something new
I have also tried a few different solutions but none of them works:
Having the client send remotes to the server each time it needed an animation done, and having the server run it (laggy, I know). This caused the same issue as here
Having the client send remotes to the server each time it needed an animation done, and having the server redistribute it to all of the clients, to have them do. This had some issues, and also it felt like a waste of resources for each client to remember 20+ animation tracks for each player that joins the game.
Is there a compelling reason to keep these three animations all separate?
I wonder if you could make a single animation that pauses when it reaches certain keyframes so that you wouldn’t have to load three to make this effect happen.
It wouldn’t serve to explain why this is happening to you, but you might get a different result!
I’m curious, when you played them from the Server, did the animations appear to glitch for both players, or just the observing player?
Is there a compelling reason to keep these three animations all separate?
Yes, so that I can mix and match different animations. I tried to use pauses by adjusting the animation speed to 0, however I had some issues so I just switched to looping a pose, which has worked well for me, so far.
Speaking about issues, I was trying to figure out why one of my animations wasn’t working, and I stumbled upon this:
I set the rightmost marker to 0:15 and the center marker to 0:07, however when I save it, it resets it to the one currently shown. I fixed this by removing the center marker. Could this be somewhat related to my other issues?
I’m curious, when you played them from the Server, did the animations appear to glitch for both players, or just the observing player?
I don’t particularly remember but I believe that it occurred for both.
An update: I have tried every possible solution that I can think of, including using AdjustWeight, AdjustSpeed, etc and none of it fixes my issue. Here is my current code and the result of it:
function play2(anim, anim2, idleanim)
if not active then return end
local t1 = tracks[anim]
local t2 = tracks[anim2]
local t3 = tracks[idleanim]
if not t1 or not t2 or not t3 then print("not found") return end
activeAnim = true
stopTracks()
t1:Play()
t1:GetMarkerReachedSignal("Pause"):Wait()
t1:AdjustSpeed(0)
t1:AdjustWeight(0.00001)
if active then
t2:Play()
else
return
end
t2:GetMarkerReachedSignal("Pause"):Wait()
t2:AdjustSpeed(0)
t2:AdjustWeight(0.00001)
if active then
current = idleanim
activeAnim = false
t3:Play()
else
current = idleanim
activeAnim = false
return
end
end
In the video, you can see how the animations play perfectly, locally, but when other players play them they appear to attempt to try to reset to the default position, before launching the new animation.
I’m getting the same issue. Animations attempt to rest before resuming another animation. Wait() empty actually does wait for a split-second, and that’s my guess as to why Roblox tries to restart the animation after it’s finished. The work-arounds I’ve been able to find is using animationTrack.Length to finish the animation exactly when it ends.
That’s not the issue that I had. Roblox won’t restart the animation unless you have animationTrack.Looped set to true.
This is what worked for me:
SOLUTION
Modify the original code/animation I provided to use only one “active” animation, anim1, to switch between idle animations (basically remove anim2). Set its Priority to Active.
For the idle animations, set their Priorities to Idle. Play this animation at the same time as the Action Animation. Once the Active animation ends, the idle one will automatically overtake it and it will transition seamlessly.
I’d suggest doing this when you create the Animation in the Animation Editor, because I have heard that if you change the priority in a Local Script, it won’t replicate to other clients.
This issue made me lose a lot of hours and braincells, so hopefully this helps you out !