AdjustSpeed() not correctly replicating to other clients

Hello everyone,
Im currently working on a fighting tool but my animations seem to be a bit broken. Im loading them on the client but when i fire them, sometimes they work and sometimes, they only work correctly on the client. On other clients, AdjustSpeed is not working and the Animation ends and is gone. I think there might be an issue with AdjustSpeed() not replicating correctly. I already checked AnimationPriority.
One little part of the ClientsCode:

tool.Equipped:Connect(function(mouse)
	standAnim:Play()
	equipped = true
	local connection
	connection = standAnim.KeyframeReached:Connect(function(name)
		if name == "AnimReady" and equipped == true then
		
			standAnim:AdjustSpeed(0)
			print(plr.Name)
			connection:Disconnect()
		end
	end)
end)

On the server is nothing considering animations.

Pics:
image
image

1 Like

You could try using Animation Events

1 Like

I used it later in the Script and it also does not work

Ah, i see. Unfortunately i’m not that good at scripting animations myself, and it’s even worse that there is nothing that could be causing it. One thing you can try, is going into Studio Settings, going to Network tab, and turning on “Show Active Animation Asset”, then check if the animation stops playing whenever it doesn’t work.

Make sure that the Animations were loaded through a server-created Animator object, as that will ensure that the animations are replicated / visible to other players. By default, there’s an Animator object in the Character’s Humanoid that should work for this if you don’t want to create one manually.

When the client loads Animations through that object, or makes any changes to an animation (including through AnimationTrack:AdjustSpeed()), it should be replicated to other players in the game.


This means that you may need to update the code in the LocalScript that loads the animation to reference the Animator object that was created by the server, then call Animator:LoadAnimation() on it.

1 Like

I replaced now hum:LoadAnimation() with this:

local plr = game.Players.LocalPlayer
local char = plr.Character
local hum = char:WaitForChild("Humanoid")

local animator = hum.Animator
local standAnim = animator:LoadAnimation(stand)
local hitAnim = animator:LoadAnimation(hit)
local blockAnim = animator:LoadAnimation(block)

I still have the same problem and it works like it did without the use of the Animator

Hmmm, without knowing more of the specifics about how everything is set up, I’m not super sure then. Based on everything I’ve read, whether it’s from the Roblox Creator Documentation site or other Developer Forum posts, it appears as if the Animator object should prevent that issue from happening.

I also went into Roblox Studio and created a modified version of the second sample codeblock provided for the AnimationTrack:AdjustSpeed() method to closely resemble the setup shown in the codeblock you posted and I haven’t been able to replicate that issue when using the Animator object.

Example codeblock

local ContentProvider = game:GetService("ContentProvider")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local Character = player.Character or player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")
local animation = Instance.new("Animation")
animation.Name = "TESTING!"
animation.Parent = Humanoid -- I tested it with or without parenting the Animation and it did not affect the results
animation.AnimationId = "rbxassetid://507770453"

ContentProvider:PreloadAsync({ animation })

local animationTrack = Animator:LoadAnimation(animation)

---

local Tool = script.Parent
Tool.Equipped:Connect(function()
	animationTrack:Play()
	
	local connection
	connection = animationTrack.KeyframeReached:Connect(function(name)
		if name == "End" then
			print(animationTrack.Speed)
			
			animationTrack:AdjustSpeed(0)
			
			warn(animationTrack.Speed)
			
			print("The AnimationTrack has been paused")
			connection:Disconnect()
		end
	end)
	
end)

Images of results

Example 1


Example 2

This is very interesting. Did you try to make the test like 1-3 times? Because the weird thing is that in my scenario, the animation/AdjustSpeed(0) plays correctly every 1/3 try. And still, only other player are seeing the animation not correct. This just makes no sense to me tbh, Im kinda clueless.

Try stopping the animation instead of setting its speed to 0:

tool.Equipped:Connect(function(mouse)
	standAnim:Play()
	equipped = true
	local connection
	connection = standAnim.KeyframeReached:Connect(function(name)
		if name == "AnimReady" and equipped == true then

			standAnim:Stop()
			print(plr.Name)
			connection:Disconnect()
		end
	end)
end)

If it works, then there might be some weird replication issues happening with the AdjustSpeed method at the moment

:Stop() is only completely ending the Animation. My goal is to keep the player in its position.
Since in other scripts, AdjustSpeed is working, there might be a problem with the rest of my code, so I just paste it here rq if anyone wants to read it:

task.wait(1)

local blockTime = 2


local stand = script.Stand
local hit = script.Hit
local block = script.Block

local tool = script.Parent

local rep = game:GetService("ReplicatedStorage").TaiJutsuEvent
local UIS = game:GetService("UserInputService")
local CP = game:GetService("ContentProvider")

local plr = game.Players.LocalPlayer
local char = plr.Character
local hum = char:WaitForChild("Humanoid")

CP:PreloadAsync({stand, hit, block})
local animator = hum.Animator
local standAnim = animator:LoadAnimation(stand)
local hitAnim = animator:LoadAnimation(hit)
local blockAnim = animator:LoadAnimation(block)

local equipped = false
local hitting = false
local blocking = false
local db = false


tool.Equipped:Connect(function(mouse)
	standAnim:Play()
	equipped = true
	local connection
	connection = standAnim.KeyframeReached:Connect(function(name)
		if name == "AnimReady" and equipped == true then
		
			standAnim:AdjustSpeed(0)
			print(plr.Name)
			connection:Disconnect()
		end
	end)
end)

tool.Activated:Connect(function()
	if equipped == true and hitting == false and blocking == false then
		hitting = true
		hitAnim:Play()
		local checking
		checking = hitAnim.KeyframeReached:Connect(function(name)
			if name == "AnimReady" and equipped == true then
				rep:FireServer("hit")
				checking:Disconnect()
			end
		end)
		
		hitAnim.Ended:Connect(function()
			hitting = false
		end)
	end
end)

tool.Unequipped:Connect(function()
	equipped = false
	standAnim:AdjustSpeed(1)
end)

UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.F and hitting == false and equipped == true and blocking == false and db == false then
		db = true
		blocking = true
		blockAnim:Play()
		local connection
		connection = blockAnim:GetMarkerReachedSignal("BlockReady"):Connect(function()
			connection:Disconnect()
			rep:FireServer("block")
			blockAnim:AdjustSpeed(0)
			task.wait(blockTime)
			blockAnim:AdjustSpeed(1)
			rep:FireServer("blockEnd")
			blocking = false
		end)
		
		blockAnim.Ended:Connect(function()
			db = false
		end)
	end
end)

Yup; it played the animation and paused it each time, and it was replicated to the other client every time. Very occasionally, however, after the Tool was unequipped, the Character’s arm would be slightly pointing forward on the screen of the other client, but that tended to be easily fixed by equipping the Tool and unequipping it again to replay the animation.

Now I am even more confused why it’s not working for your use case, since the full codeblock you posted doesn’t seem like there’s anything wrong that would be causing that unintended behavior. Sorry that I couldn’t help that much!

2 Likes

Still thank you very much! May do you know other opportunities than using AdjustSpeed(0) to keep the player in a specifiq position?

1 Like

Unfortunately, I think you might be experiencing some kind of weird bug, possibly related to an animation replication bug I’ve recently encountered myself:

If the issue is being created due to the AdjustSpeed method itself, then a possible workaround might involve doing something like this:

task.wait(1)

local blockTime = 2


local stand = script.Stand
local hit = script.Hit
local block = script.Block

local tool = script.Parent

local rep = game:GetService("ReplicatedStorage").TaiJutsuEvent
local UIS = game:GetService("UserInputService")
local CP = game:GetService("ContentProvider")

local plr = game.Players.LocalPlayer
local char = plr.Character
local hum = char:WaitForChild("Humanoid")

CP:PreloadAsync({stand, hit, block})
local animator = hum.Animator
local standAnim = animator:LoadAnimation(stand)
local hitAnim = animator:LoadAnimation(hit)
local blockAnim = animator:LoadAnimation(block)

local equipped = false
local hitting = false
local blocking = false
local db = false


tool.Equipped:Connect(function(mouse)
	standAnim:Play()
	equipped = true
	local connection
	connection = standAnim.KeyframeReached:Connect(function(name)
		if name == "AnimReady" and equipped == true then

			local timePosition = standAnim.TimePosition
			standAnim:Play(0, 1, 0)
			standAnim.TimePosition = timePosition
			print(plr.Name)
			connection:Disconnect()
		end
	end)
end)

tool.Activated:Connect(function()
	if equipped == true and hitting == false and blocking == false then
		hitting = true
		hitAnim:Play()
		local checking
		checking = hitAnim.KeyframeReached:Connect(function(name)
			if name == "AnimReady" and equipped == true then
				rep:FireServer("hit")
				checking:Disconnect()
			end
		end)

		hitAnim.Ended:Connect(function()
			hitting = false
		end)
	end
end)

tool.Unequipped:Connect(function()
	equipped = false
	standAnim:AdjustSpeed(1)
end)

UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.F and hitting == false and equipped == true and blocking == false and db == false then
		db = true
		blocking = true
		blockAnim:Play()
		local connection
		connection = blockAnim:GetMarkerReachedSignal("BlockReady"):Connect(function()
			connection:Disconnect()
			rep:FireServer("block")
			blockAnim:AdjustSpeed(0)
			task.wait(blockTime)
			blockAnim:AdjustSpeed(1)
			rep:FireServer("blockEnd")
			blocking = false
		end)

		blockAnim.Ended:Connect(function()
			db = false
		end)
	end
end)

which replays the animation with its speed set to 0 but uses the TimePosition property to jump back to the correct animation time, which should pause the animation in the same manner as adjusting its speed to 0

2 Likes

This works a bit buggy when the server just got started but when fully loaded, it works perfect, thank you very much! Also, you may want to add the AdjustSpeed(0) bug to your bug report?

2 Likes