Animation Sync Script Help

  1. What do you want to achieve?

A Full on Working Sync Command that supports both AnimationTrack changing and ability to sync one person onto another designated person for any dance they are playing.

  1. What is the issue?

ATM of version 1.0 of the SYNC command. You are able to sync to a player dance but, if a player changes their animationId or animation. It will stop syncing the player with the right dance. So I need to add a AnimationTrack:Change or animationId:Change and basically then put that as the dance.

  1. What solutions have you tried so far?

There hasn’t been any solutions atm, Im not familiar with animations at all. So if anyone can lead me in the right direction it would be greatly appreciated!

Heres the working VERISON 1.0 Source code -

--[[
	@author TwinPlayzDev_YT
	@credit Neutron_Flow (helped with animator parts)
	@since 2/15/2021
	This script will let players sync animations with other players.
	Place this script in ServerScriptService.
--]]

--[ SERVICES ]--

local Players = game:GetService("Players")

--[ MAIN LOCALS ]--

local syncthing = "/sync ([%w_]+)" --this is a string pattern that should match any player username
local leavesync = "/leavesync" -- string for leaving the sync

--[ FUNCTIONS ]--

game.Players.PlayerAdded:Connect(function(localplr)
	localplr.Chatted:Connect(function(msg)
		
		
		--[{ JOINSYNC }]--
		
		local subjectName = msg:match(syncthing) -- checking to see if it matches text
		
		if subjectName then
			local subject = game.Players:FindFirstChild(subjectName)
			if subject then
				
				-- play animation
				local humanoid = localplr.Character:WaitForChild("Humanoid") -- player humanoid
				local humanoid2 = subject.Character:WaitForChild("Humanoid") -- subject humanoid
				local animator = humanoid:WaitForChild("Animator") -- player animator
				local animator2 = humanoid2:WaitForChild("Animator") -- subject animator
				local AnimationTracks = animator2:GetPlayingAnimationTracks() -- subject animation tracks
				
				for _, v in pairs(AnimationTracks) do
					local track = animator:LoadAnimation(v.Animation) -- requires an animation object
					track.Priority = Enum.AnimationPriority.Action
					track:Play()
					track.TimePosition = v.TimePosition
					track:AdjustSpeed(v.Speed)
				end
			end 
		end
		
		--[{ LEAVESYNC }]--
		
		local leaveName = msg:match(leavesync) -- checking to see if it matches text
		
		if leaveName then
			
			-- stop animation
			local humanoid = localplr.Character:WaitForChild("Humanoid") -- player humanoid
			local animator = humanoid:WaitForChild("Animator") -- player animator
			local AnimationTracks = animator:GetPlayingAnimationTracks() -- player animation tracks
			
			for _,v in pairs(AnimationTracks) do
				v:Stop()
			end
		end
	end)
	
	
end)

If you sync AnimationTracks on the Server using TimePosition, they will only be playing in sync on the server. They are unlikely to be in sync on any client, because it takes time for the animations to load on the clients, and by the time the TimePosition value replicates to each client, it’s stale by at least the time it took the message to travel the internet from server to client. And if the animation that you’re trying to sync to was started on the first player’s client, then the TimePosition the server has is already off by at least the client-to-server message time for that player too, so the player who chatted “sync” sees themselves de-synced by half their ping plus half the ping of the other player (in reality, a little bit more than this).

If you want players dancing in sync, you have to wait until the new animation tracks are playing on the client, and then sync them locally by setting the TimePositions to be equal from a LocalScript.

1 Like

Okay Ill look more into this, I under stand your point of saying that the Syncs are off. Because yes ATM the syncs are not synced correctly.

Ill see what I can do.

Any idea where to start? Or any links would be helpful.

1 Like

Just do what you’re already doing, except instead of setting TimePositions of the tracks to be equal on the server, relay the event (FireAllClients) back to everyone and do the TimePosition setting in the receiving LocalScript.

The “gotcha” you have to be aware of is that when a LocalScript sets the TimePosition of an AnimationTrack that is being played by that client’s player’s character, the change replicates back to the Server and then to everyone, which could cause de-sync again. So when the local player is involved (one of the syncing parties), you sync the other players’ characters to theirs, not the other way around. And you do it that way on every client.

2 Likes

I’ve semi sorted out the syncing issue but still got a couple more problems though this is what I did:

On the server script I put this:

And the on a local script I put this:

The problem is after the player syncs once and the player leaves the sync and trys to sync again it doesn’t work.

2 Likes

Where did you put this local script by chance?

This is very cool, I like the way you approached this.

I put it in startercharacterscripts but i think it should work in starterplayerscripts too.

1 Like