Should I fire to the specific client playing the animation or fire to all clients?

My current approach is :FireClient() to tell the player who started a action to play the animation. The client then plays the animation locally, and the server replicates that animation to other clients.

The problem is that if the client that starts the animation has high latency, the animation starts late for other players.

My idea is to use :FireAllClients() and send the player whose character should play the animation. Each client would then locally play the animation on that character.

Is this a better approach, or is there a more reliable way to handle this problem?

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")

local startAnimationEvent = game.ReplicatedStorage.Events.Animate.StartAnimation
local stopAnimationEvent = game.ReplicatedStorage.Events.Animate.StopAnimation

local playingAnimations = {}

startAnimationEvent.OnClientEvent:Connect(function(animation)
	local track = animator:LoadAnimation(animation)

	playingAnimations[animation] = track

	track:Play()
end)

stopAnimationEvent.OnClientEvent:Connect(function(animation)
	local track = playingAnimations[animation]

	if not track then return end
	track:Stop()
	track:Destroy()
	playingAnimations[animation] = nil
end)
2 Likes

Does the server actually need to tell the client to play the animation? usually, a local script can play the animation directly on the local players character, and Roblox will replicate it to the other players automatically.

Yes server is handling the logic when animation needs to start playing and tells the client when to start playing it

What kind of game are you making? if the animation is just an effect for something, i dont think the small latency really matters

I dont exactly get the problem
If you want to sync animation you can just speed it up (i think its called interpolation) for other clients
By reciving timestamp workspace:GetServerTimeNow()
So the server (or the client but please fool proof this one) sends the timestamp as to when they started the animation and other clients just math.max(workspace:GetServerTimeNow()/timestamp,1) (i hope its the right order of division) to retrive speed of animation
and then just :AdjustSpeed() or whatever

animators that are owned by a client via network ownership are automatically replicated if you play it from the client or server, so to remove the latency problem you just need to play the animation on the server, assuming you already have the animations loaded. if not, you will have to call fireallclients with a synced start time (such as workspace:GetServerTimeNow()), play the animation, and skip to workspace:GetServerTimeNow() - StartTime. this may or may not have a few milliseconds of offset between clients but it should be frame-perfect if you do the skipping method

if you want the animation to rubber-band instead of immediately skipping, you will need to implement some type of math equation to rubber band the animation to the intended time. there is an equation i posted that does this for multiple sound emitters so you may have to dig through my posts but that is the only realistic way of syncing the animations frame-perfectly

2 Likes

Since you made a variable of the humanoid’s animator you can use that to play the animation directly because Roblox automatically replicates it through all clients almost instantly without using remote events.

If your server handles the logic for when an animation starts playing anyways, then you can just load and play the animation directly on the server