Need help porting crouch animation to server side so others can see it

Hello I am working on this crouch animation and it works fine on a local script but the problem is that other people cant see me crouching and when I try to port it to a server sided script it lags and has delays and other problems like messing up, here’s my code it is in a local script inside starter character scripts thanks in advance.

local userinputservice = game:GetService("UserInputService")
local charecter = script.Parent
local humanoid = charecter:WaitForChild("Humanoid")
local crouchAnm = humanoid:LoadAnimation(script:WaitForChild("Crouch Walking"))
local isCrouching = false
local AnimationValue = script.Parent:WaitForChild("AnimationValuesFolder").IsCrouching
local RS = game:GetService("ReplicatedStorage")
local isCrouchingEvent = RS.AnimationEvents.IsCrouchingEvent
local isCrouchingEventNot = RS.AnimationEvents.IsNotCrouching
local CrouchIdelAnm = humanoid:LoadAnimation(script:WaitForChild("Crouch Walk Idle"))



userinputservice.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.LeftControl then
		if not isCrouching then
			
			isCrouching = true
			CrouchIdelAnm:Play(0.25)
			humanoid.WalkSpeed = 9
			humanoid.JumpPower = 0

			humanoid.Running:Connect(function(speed)
				if isCrouching then
					if speed > 0 then
						CrouchIdelAnm:Stop(0.25)
						crouchAnm:Play(0.25)
					else
						crouchAnm:Stop(0.25)
						CrouchIdelAnm:Play(0.25)
					end
				end
			end)
			
		else
			
			AnimationValue.Value = false
			crouchAnm:Stop(0.25)
			CrouchIdelAnm:Stop(0.25)
			humanoid.WalkSpeed = 12
			humanoid.JumpPower = 50
			isCrouching = false

			
		end
		
	end
end)

FYI some of the local functions are unused.

Animations should replicate automatically from client to server and server to client. The replication is caused by the Animator object. So there’s most likely something wrong with that here. If I remember correctly, when you load an animation, the Animator is created, but only replicates if it’s created by the server. So you need to create an Animator object from the server.

1 Like

As long as the Animator instance is a descendant of the player’s character model any and all played AnimationTrack instances through that Animator instance will be replicated to the server. When loading the Animation instance which returns an AnimationTrack instance inside of a local script for the first time it’s important to wait for the Animator instance to be replicated from the server to the client before attempting to load the Animation instance.

1 Like
local UIS = game:GetService("UserInputService")
local crouchAnim = script:WaitForChild("Crouch Walking")
local crouchIdleAnim = script:WaitForChild("Crouch Walk Idle")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local crouchAnimLoad = animator:LoadAnimation(crouchAnim)
local crouchIdleAnimLoad = animator:LoadAnimation(crouchIdleAnim)

local animationValue = script.Parent:WaitForChild("AnimationValuesFolder"):WaitForChild("IsCrouching")
local rs = game:GetService("ReplicatedStorage")
local isCrouchingEvent = rs:WaitForChild("AnimationEvents"):WaitForChild("IsCrouchingEvent")
local isCrouchingEventNot = rs:WaitForChild("AnimationEvents"):WaitForChild("IsNotCrouching")
local isCrouching = false

UIS.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end
	
	if input.KeyCode == Enum.KeyCode.LeftControl then
		if not isCrouching then
			isCrouching = true
			animationValue.Value = true
			humanoid.WalkSpeed = 9
			humanoid.JumpPower = 0
			humanoid.JumpHeight = 0
			humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
				if isCrouching then
					if humanoid.WalkSpeed > 0 then
						crouchIdleAnimLoad:Stop(0.25)
						crouchAnimLoad:Play(0.25)
					elseif humanoid.WalkSpeed <= 0 then
						crouchAnimLoad:Stop(0.25)
						crouchIdleAnimLoad:Play(0.25)
					end
				end
			end)
		elseif isCrouching then
			isCrouching = false
			animationValue.Value = false
			crouchAnimLoad:Stop(0.25)
			crouchIdleAnimLoad:Stop(0.25)
			humanoid.WalkSpeed = 12
			humanoid.JumpPower = 50
			humanoid.JumpHeight = 7.2
		end
	end
end)
1 Like

You may want to add a debounce to prevent rapid crouching.

1 Like

This isn’t true. Read the article I sent.

The Animator object must be initially created on the server and replicated to clients for animation replication to work at all.

1 Like

I was referring to replication of the played AnimationTrack instance to the server for other clients to observe (you don’t need to keep reloading Animation instances on the server using the Animator object of the player’s character).

1 Like

I never said you have to keep reloading animation instances, and you shouldn’t be loading them from the server here anyways. The animator object simply needs to be created by the server, or added inside of the Humanoid through explorer if it’s a StarterCharacter.

1 Like
local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local human = character:WaitForChild("Humanoid")
		local animator = human:WaitForChild("Animator")
	end)
end)

Simple server script which should force the server to load the Animator object of all player’s characters when they reload/spawn etc.

1 Like

okay so this sorta fixed it i think but now people cant see the idle crouch animation when the player stops but the walking animation works fine

local UIS = game:GetService("UserInputService")
local crouchAnim = script:WaitForChild("Crouch Walking")
local crouchIdleAnim = script:WaitForChild("Crouch Walk Idle")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local crouchAnimLoad = animator:LoadAnimation(crouchAnim)
local crouchIdleAnimLoad = animator:LoadAnimation(crouchIdleAnim)

local animationValue = script.Parent:WaitForChild("AnimationValuesFolder"):WaitForChild("IsCrouching")
local rs = game:GetService("ReplicatedStorage")
local isCrouchingEvent = rs:WaitForChild("AnimationEvents"):WaitForChild("IsCrouchingEvent")
local isCrouchingEventNot = rs:WaitForChild("AnimationEvents"):WaitForChild("IsNotCrouching")
local isCrouching = false

UIS.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end

	if input.KeyCode == Enum.KeyCode.LeftControl then
		if not isCrouching then
			isCrouching = true
			animationValue.Value = true
			humanoid.WalkSpeed = 9
			humanoid.JumpPower = 0
			humanoid.JumpHeight = 0
			humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
				if isCrouching then
					if humanoid.WalkSpeed > 1 then
						crouchIdleAnimLoad:Stop(0.25)
						crouchAnimLoad:Play(0.25)
					elseif humanoid.WalkSpeed <= 1 then
						crouchAnimLoad:Stop(0.25)
						crouchIdleAnimLoad:Play(0.25)
					end
				end
			end)
		elseif isCrouching then
			isCrouching = false
			animationValue.Value = false
			crouchAnimLoad:Stop(0.25)
			crouchIdleAnimLoad:Stop(0.25)
			humanoid.WalkSpeed = 12
			humanoid.JumpPower = 50
			humanoid.JumpHeight = 7.2
		end
	end
end)

This should play the other animation when walkspeed is below 1, providing both of the animations have been created correctly.

1 Like

thanks, ill try it as soon as my animator friend comes on so he can update the animation priority right, ill keep you posted, any chance you can explain better on what you meant by created right?

Yeah, you may need to play around with the animation priority and I was referring to both animations being different from one another & uploaded to the same account etc.

1 Like

yeah it didnt work, idle animation is the priority of the idle anm and same for walking, walking works fine but with your script the idle does not even take effect when i stop

nvm man thanks, ill try to find a way around it and ill update this post when i do, if you have suggestions please do share

I fixed it, I just had to put an animator object inside the humanoid of the player, I did it from the workspace as I had a custom character but you can do it with a script too, this is my local script in StarterCharacterScripts:

local userinputservice = game:GetService("UserInputService")
local charecter = script.Parent
local humanoid = charecter:WaitForChild("Humanoid")
local crouchlanm = humanoid:LoadAnimation(script:WaitForChild("Crouch Walking"))
local StopAnimation = humanoid:LoadAnimation(script:WaitForChild("Crouch Walk Idle"))
local isCrouching = false
-------------------------------------------------------------------------------


-------------------------------------------------------------------------------
userinputservice.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.LeftControl then
		if not isCrouching then -- if not already crouched then do this
			
			isCrouching = true
			StopAnimation:Play(0.25)
			humanoid.WalkSpeed = 6
			humanoid.JumpPower = 0
			
		else -- if already crouching then do this
			
			isCrouching = false
			crouchlanm:Stop(0.25)
			StopAnimation:Stop(0.25)
			humanoid.WalkSpeed = 12
			humanoid.JumpPower = 50
			
		end
	end
end)
-------------------------------------------------------------------------------


-------------------------------------------------------------------------------
humanoid.Running:Connect(function(speed)
	if isCrouching == true then
		if speed > 0 then -- if is moving then\
			
			StopAnimation:Stop(0.25)
			crouchlanm:Play(0.25)

		else -- if is no longer moving then
			
			crouchlanm:Stop(0.25)
			StopAnimation:Play(0.25)
			end
		end
end)

Yeah, you need to create the animator object from the server first so that when the animations are played locally they replicate to the server, sorry for not mentioning this as I had thought you were aware of this already.

I was, but people said that Humanoid:LoadAnimation would automatically make an animator but it did not for some reason, so i had to put it in by hand or by script which worked, thanks for all your help man.