Animation.TimePosition Help / Problem

So recently , I’ve been coming along a sort of problem with animations and dances. I’ve been working on getting a /sync and /leavesync command like the game Animations:MoCap.

The problem now when you normally are syncing to a player you want it to match the exact and I mean exact time position of the subjects dance animations.

What I have so far :

--[[
	@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:Play()
					track.TimePosition = v.TimePosition
				end
				
				print("dance played")
				
			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
			
			print("dance stopped")
			
		end
	end)
	
	
end)

What part i’m looking at -

for _, v in pairs(AnimationTracks) do
		local track = animator:LoadAnimation(v.Animation) -- requires an animation object
		track:Play()
		track.TimePosition = v.TimePosition
end

Ive been doing some research and getting help from a friend @Neutron_Flow Credits to him for helping me out.

He told me that its going to be harder to now try and get the time position because of this -

TimePosition Documentation

This item is not replicated across Roblox’s server/client boundary.

If anyone has any idea how I can go around this, or maybe just maybe easily fix this. This script is in ServerScriptService and is just grabbing the humanoids animations and playing them the same way as others. But the .TimePosition is the problem right now.

2 Likes

Yes but what does this have to do for .TimePosition?

Thanks for the advice though.

My point is that instead of grabbing humanoid animations, you can store the AnimationObjects when they get played and check the time position when necessary.

1 Like

AnimationController:GetPlayingAnimationTracks() is deprecated, as well as Humanoid:GetPlayingAnimationTracks(). However, the script clearly uses Animator:GetPlayingAnimationTracks() which is not deprecated.

Also, AnimationObject is not a thing as far as I’m aware. There is Animation, but that does not have a TimePosition. Only AnimationTrack has TimePosition, and it’s not replicated across the client/server boundary. Which is what this post is about.

1 Like

Sorry, I was thinking of AnimationTracks. You can store these in a module script when they’re played and reference them later.

1 Like

Use :AdjustSpeed(YourSpeed)

YourAnimationTrack:AdjustSpeed(YourSpeed)
1 Like

How could I possibly get the v.Length or speed? Correctly?

for _, v in pairs(AnimationTracks) do
					local track = animator:LoadAnimation(v.Animation) -- requires an animation object
					local speed = v.Length / v.Speed
					track:Play()
					track.TimePosition = v.TimePosition
					track:AdjustSpeed(speed)
				end

This seemed to be very fast.

Then I used

for _, v in pairs(AnimationTracks) do
					local track = animator:LoadAnimation(v.Animation) -- requires an animation object
					track:Play()
					track.TimePosition = v.TimePosition
					track:AdjustSpeed(v.Speed)
				end

this seem to work, but still wasn’t syncing correctly?

Try using Humanoid:LoadAnimation() and setting animation priority to action!

What are you trying to say, I understand theirs that part right now we have

local track  = animator:LoadAnimation(v.Animation)

But how would
setting the animation priority to action change anything?

It will not override other animations. Like walking, idle, etc.

1 Like

Just be aware that setting AnimationTrack.Priority from a script does not replicate in either direction, so if you fix it in a local script, it’s only fixed for that client and no one else will see them animating the way they do. You either have to set in everywhere (server, and all clients for all avatars), or you set it to Action in the animation editor and republish the animation. Republishing is the preferred way, having to set it from script everywhere is a kind of a mess because normally you would not write LocalScript code that modifies other players’ avatars besides your own.

1 Like

Well so I did just set the animation priority to Action, and it seemed to help a little bit.

Yes this script is in ServerScriptService Too.