How do you line two animations smoothly?

For the last month or so I have struggled with this problem. I am using a module I made for my cut scenes but to animate I teleport the character to the place where the animation has progressed, so the player dost go back to where he was before the animation.

For instance if I wanted a character to walk over to a place and them jump. I would run the walkAnimation and then so the character doesn’t bounce back at the end of the animation, I teleport the character(with SetPrimaryPartCFrame) to the pose where the animation ended. This way I can just play the jump animation and the character is at the same place. However the problem is I can never time the teleport with the end of the animation, so there is always a flicker.

See:
com-video-to-gif

My code is super complex but this is the executed part:

for i,v in ipairs(Character.Value.Humanoid:GetPlayingAnimationTracks()) do --Stoping all playing animations
	v:Stop()
end
		
local Animation = Character.Value.Humanoid:LoadAnimation(Animation) -- Geting the Animation tract
		
repeat wait(0.05) until Animation.Length ~= 0 -- Waiting for animation to load
		
Animation:Play() 
		
while wait() do -- waiting until animation almost over
	print(Animation.TimePosition)
	if Animation.TimePosition > Animation.Length - 0.1 then 
		break
	end
end

Animation:Stop()
Character.Value:SetPrimaryPartCFrame(AfterTorsoPosePartCFrame)

Are you playing the animation on the client or the server? Are you setting the CFrame on the client or server?

Server. The game is solo so I am not worrying about filtering enabled.

If you’re doing everything from the server, it should be pretty easy to synchronise. You can use AnimationTrack.Stopped to detect when an AnimationTrack stops playing. I’ve also removed your initial repeat statement that waits until the track loads, since it seems unnecessary.

local character = Character.Value
local humanoid = character.Humanoid

-- Stop all playing AnimationTracks.
for _, animation_track in ipairs(humanoid:GetPlayingAnimationTracks()) do
	animation_track:Stop()
end
-- Get and play AnimationTrack.
local animation_track = humanoid:LoadAnimation(animation)
animation_track:Play() 
-- Wait until the AnimationTrack stops, then move character.
animation_track.Stopped:Wait()
character:SetPrimaryPartCFrame(AfterTorsoPosePartCFrame)

I hope this helped! Let me know if you have any questions or there’s any issues. :slight_smile:

1 Like

Still is there:

com-video-to-gif%20(1)

That’s an issue with your animation, then. Or, would you like the character to change position during the animation? With my current code, the character will teleport that position as soon as the animation is fully finished.

I don’t care as long as it is smooth.

This is the animation:
com-video-to-gif%20(2)

Ah, I understand your expected result more clearly now. I don’t believe that there’s a particularly good way to do this using your method (please correct me if I’m wrong). Personally, I would have the animation play as normal, yet the animation itself should keep the character stationary. You can then move the character appropriately outside of the animation (perhaps at certain Keyframes using AnimationTrack.KeyframeReached).

Gosh! Please tell me there is a easier way. I don’t understand keyframes.

I’m personally not that familiar with any other way. You can rename Keyframes yourself in the built-in animation editor.

1 Like

Not sure if this is exactly what you’re looking for but if you do some sort of transaction like changing the camera’s position as the user gets choppy so nobody notices it

This is a really cheeky bypass so I wouldn’t rely on it.

1 Like

Yeah but Id can’t do that every time.

There isn’t currently a 100% surefire way to prevent this from happening, but to make it look a slight bit smoother, you can stop the animtrack with a float speed of 0, when it finishes, to make it snap back into the position a bit faster.

Due to personal experiences I’ve tried my best to prevent it from happening, but I couldn’t find a way to completely avoid it.

Edit: This is how I have it set up:

-- defining the animation here
animTrack:Play()
animTrack.Stopped:wait()
Person:SetPrimaryCFrame(Person.Torso.CFrame)
animTrack:Stop(0)

Would that not be pointless? You’re waiting until after the animation track stops to stop the animation track, unless I’m missing something.

@Suitable_Jay I faced the same problem before, the solution is to use body movers to move the person upstairs and making the animation in place (torso y-axis/up does not change).

It takes longer for it to stop then to move. So it first moves, then stops the animation.

The left bot is the one without the floatspeed set to 0, the right bot is set to 0.

if you look closely you’ll see the left one is taking longer to snap back into position, whereas the Right one is practically instant

3 Likes
1. animationTrack:AdjustSpeed(0)
2. animationTrack:Play()

Is this what you mean @Liliardio?

no that would would just freeze the animation, I mean something more like

local Anim = Instance.new('Animation')
Anim.AnimationId = 'rbxassid://IDNUM'

local AnimTrack = Human:LoadAnimation(Anim)
AnimTrack:Play()
AnimTrack.Stopped:wait() -- Wait until the animation ends
Character:SetPrimaryCFrame(Character.Torso.CFrame) -- Sets the CFrame to the position of the Torso where the animation Concluded
AnimTrack:Stop(0) -- Makes sure the Animation starts ASAP

You can also add a fail safe in case the animation ends prematurely to still teleport them to the end by adding this before setting the PrimaryPart’s CFrame

animTrack.TimePosition = animTrack.Length
animTrack:AdjustSpeed(0)
4 Likes

Yay! Thank you. This community is so helpful.

2 Likes