Animations not replicating properly to other clients

I have a client animation to equip a gun. I have two animations loaded (animation track) on a ModuleScript (kept in ReplicatedStorage) that has a function to play the animations. One is to equip the gun, and another is to switch over to an idle animation. This works on the client, although to other clients observing this client there’s a delay in between the equip and idle animation. I’m not sure why it is replicating improperly.

ModuleScript func to equip gun:

local isEquipping = false
function DC15EAnimations.Equip(player)
	warn("Playing from module")
	local character = player.Character or player.CharacterAdded:Wait()
	local humanoid = character:WaitForChild("Humanoid")
	local animator = humanoid:WaitForChild("Animator")
	local equipAnimation = DC15EEquip
	local idleAnimation = DC15EIdle

	local equipTrack = animator:LoadAnimation(equipAnimation)
	local idleTrack = animator:LoadAnimation(idleAnimation)

	equipTrack:Play()
	isEquipping = true

	-- Event handler for when the equip animation finishes
	local function onEquipAnimationFinished()
		if isEquipping then
			idleTrack:Play()
			equipTrack:Stop()
		end
	end

	-- Connect the event handler to the equip animation's stopped event
	equipTrack.Stopped:Connect(onEquipAnimationFinished)
end

LocalScript under gun:

-- Equip tool, play animation, sound effects and then display gun in appropriate time
tool.Equipped:Connect(function()
	DC15EAnimations.Equip(player)
	SoundEffectsModule.EquipGun()
	
	wait(DC15EAnimations.DC15EBufferTime) -- Wait for appropriate time in animation before making gun model visible
	for i, v in pairs(tool:GetChildren()) do
		if not (v:IsA("LocalScript") or v.Name == "BodyAttach") then
			v.Transparency = 0
		end
	end
end)

I’ve tried to reroute through a server script, so the module is called from the server (from a RemoteEvent from the client) but this only made the situation worse, where even the client itself had the delay.

What client sees:
https://gyazo.com/be9d3a3043611b132c48a6a395d93a01

What other clients see:
https://gyazo.com/aebfe95bdfb1b7be9c059e36d56e5edb

Note: I’m aware that the gun model also loads in at the wrong time to other clients; this is a separate issue I’m aware of and more confident with fixing. For now, I’m only interested in the animation.

Help would be appreciated!

1 Like

I honestly don’t think there is much you can do here… Have you tried adjusting the speed of the animation?

1 Like

This sounds honestly just like a server/ping issue, you got to remember that replication is not instantaneous and so there will always be a slight delay between what happens on the client and what happens on another persons client, that can include that slight stutter problem between switching animations.

Though there may be a few methods you can try that may help.

local equipTrack = animator:LoadAnimation(equipAnimation)
local idleTrack = animator:LoadAnimation(idleAnimation)

Have these idle and equip tracks loaded before you call the equip, you can do this by making a table in a module script and when the player joins the game it loads the animation to that table, this way the animation is already loaded before you use it. You could try this method with the server method you mention in your post and that might help too although I don’t recommend running animations through the server.

The next possible method which may be the weirdest one, since I’ve never tested it. This method would be FireToAllClients the animation you want to use and the target and have the animation fire on each individual person client. I’m honestly not sure how that would look but it may the fix problem.

-- Server
local AnimationEvent = -- Event for firing to all clients
local Target = Workspace.StraightScared.Humanoid 
local theTrack = idleAnimation -- The animation track
AnimationEvent:FireAllClients(Target, theTrack)

-- Client
local AnimationEvent = -- Event for firing to all clients
AnimationEvent.OnClientEvent:Connect(function(Target, theTrack)
Target:LoadAnimation(theTrack):Play()
end)

You can try loading the animation on the server first and sending that load animation through the fireallclients event for this method.

and I guess the final thing you could do and maybe the easiest method would be to start the idle track before the equip track finishes and adding a blend and weight to the idle track

task.wait(equipTrack.Length - 0.2) -- Use this instead of  using the animation stopped function event
idleTrack:Play(0.5 --[[Blend]], 1.1 --[[Weight]])
task.wait(0.15)
equipTrack:Stop()

Also just as a quick tip add the blend to animations like equiping and idle animations and really any animation for more fluid animatiosn.

equipTrack:Play(0.5)

You can do the same thing with stopping an animation basically it doesn’t make the animation stop or start immediately but starts it up depending on how much time you gave the start up and it blends other animations together. Though it only really matters much if the animation is like for example a run animation which needs build up before you start instantly sprinting or slowing down when you stop.

2 Likes

I think what could fix this would be to use animation priorities. You to play both animations at the same time, but set the priority of the equip animation higher than the idle. When the equip animation ends, the idle will take over.

2 Likes

Thanks for the detailed response! I had tried experimenting with blending and animation weights, but they also didn’t replicate properly unfortunately. Out of curiosity, could I also ask what the actual difference between task.wait and wait is? I’m still learning the specifics of ROBLOX programming, coming from a career programming job :slight_smile:

Thanks for this! This was the solution; feels obvious with hindsight. Just got tunnel vision on trying to reduce the delay between animations as much as possible and didn’t even think about just having one overwrite.

task.wait is the newer replacement for wait and you should always use it. Its more accurate. Old wait still exists to prevent old code from breaking

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.