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)
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.
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
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.