[UNSOLVED] help needed on improving this movement script

this is a poorly-put-together movement script where pressing q and e will either increase or decrease the player’s speed depending on their current state of movement.
the script functions fine, but has some issues:

  • i need to make room/readability for the addition of flying player animations, other emote animations (besides sitting), and attack/tool-based animations: but the script is already fairly fragile in its current state
  • animations tend to bug out on turns/slopes.
  • movement animations will not change mid-walk (ex: if i click E to speed up while walking, i want it to automatically begin trotting without having to stop the player/return to idle)
  • im just a poor scripter and need to improve the script lmao
  • chart for clarification on what this script does on the fourth post in the thread.

thanks in advance for any help

local uis = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:FindFirstChild("Humanoid")


-- movement tracks
local walk = script:WaitForChild("Walk")
local walkTrack = humanoid.Animator:LoadAnimation(walk)
local idle = script:WaitForChild("Idle")
local idleTrack = humanoid.Animator:LoadAnimation(idle)
local trot = script:WaitForChild("Trot")
local trotTrack = humanoid.Animator:LoadAnimation(trot)
local run = script:WaitForChild("Run")
local runTrack = humanoid.Animator:LoadAnimation(run)
local crouch = script:WaitForChild("Crouch")
local crouchTrack = humanoid.Animator:LoadAnimation(crouch)
local sneak = script:WaitForChild("Sneak")
local sneakTrack = humanoid.Animator:LoadAnimation(sneak)

-- task identifiers
local emote = false
local speedwalk = true
local speedtrot = false
local speedrun = false
local speedsneak = false
local currentspeed = false

-- movement script

uis.InputBegan:Connect(function(input, gpe)
	if gpe then return end
	if input.KeyCode == Enum.KeyCode.E and speedsneak == true then -- begin walking
		speedwalk = true
		speedsneak = false
		
		speedtrot = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.E and speedwalk == true then -- begin trotting
		speedwalk = false
		speedtrot = true
		
		speedsneak = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.E and speedtrot == true then -- begin running
		speedtrot = false
		speedrun = true
		
		speedsneak = false
		speedwalk = false
	elseif input.KeyCode == Enum.KeyCode.Q and speedrun == true then -- slow to trot
		speedrun = false
		speedtrot = true
		
		speedsneak = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.Q and speedtrot == true then -- slow to walk
		speedtrot = false
		speedwalk = true
		
		speedsneak = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.Q and speedwalk == true then -- slow to sneak
		speedwalk = false
		speedsneak = true
		
		speedtrot = false
		speedrun = false
	end
end)

humanoid.Running:Connect(function(speed)
	if speedwalk == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		if speed > 0 and emote == false then
			idleTrack:Stop()
			walkTrack:Play()
			humanoid.WalkSpeed = 12
			currentspeed = 12
		elseif emote == false then
			idleTrack:Play()
			walkTrack:Stop()
		end
	end
	if speedtrot == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		if speed > 0 and emote == false then
			idleTrack:Stop()
			trotTrack:Play()
			humanoid.WalkSpeed = 20
			currentspeed = 20
		elseif emote == false then
			idleTrack:Play()
			trotTrack:Stop()
		end
	end
	if speedrun == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		if speed > 0 and emote == false then
			idleTrack:Stop()
			runTrack:Play()
			humanoid.WalkSpeed = 35
			currentspeed = 35
		elseif emote == false then
			idleTrack:Play()
			runTrack:Stop()
		end
	end
	if speedsneak == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		if speed > 0 and emote == false then
			crouchTrack:Stop()
			sneakTrack:Play()
			humanoid.WalkSpeed = 6
			currentspeed = 6
		elseif emote == false then
			crouchTrack:Play()
			sneakTrack:Stop()
		end
	end
end)

idleTrack:Play()

-- END OF MOVEMENTS

-- EMOTES

-- EMOTE LIST
local sit = script:WaitForChild("Sit")
local sitTrack = humanoid.Animator:LoadAnimation(sit)

uis.InputBegan:Connect(function(input, gpe)
	if gpe then return end
	if input.KeyCode == Enum.KeyCode.R then
		if emote == false then
			emote = true
			sitTrack:Play()
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
			print("now sitting")
		else
			emote = false
			sitTrack:Stop()
			humanoid.WalkSpeed = (currentspeed)
			humanoid.JumpPower = 35
			print("now unsitting")
		end
	end
end)
3 Likes

local uis = game:GetService(“UserInputService”)
local character = script.Parent
local humanoid = character:FindFirstChild(“Humanoid”)

– movement tracks
local walk = script:WaitForChild(“Walk”)
local walkTrack = humanoid.Animator:LoadAnimation(walk)
local idle = script:WaitForChild(“Idle”)
local idleTrack = humanoid.Animator:LoadAnimation(idle)
local trot = script:WaitForChild(“Trot”)
local trotTrack = humanoid.Animator:LoadAnimation(trot)
local run = script:WaitForChild(“Run”)
local runTrack = humanoid.Animator:LoadAnimation(run)
local crouch = script:WaitForChild(“Crouch”)
local crouchTrack = humanoid.Animator:LoadAnimation(crouch)
local sneak = script:WaitForChild(“Sneak”)
local sneakTrack = humanoid.Animator:LoadAnimation(sneak)

– task identifiers
local emote = false
local currentspeed = 0

– movement functions
local function playIdle()
walkTrack:Stop()
trotTrack:Stop()
runTrack:Stop()
crouchTrack:Stop()
sneakTrack:Stop()
idleTrack:Play()
end

local function playWalk()
idleTrack:Stop()
trotTrack:Stop()
runTrack:Stop()
crouchTrack:Stop()
sneakTrack:Stop()
walkTrack:Play()
humanoid.WalkSpeed = 12
currentspeed = 12
end

local function playTrot()
idleTrack:Stop()
walkTrack:Stop()
runTrack:Stop()
crouchTrack:Stop()
sneakTrack:Stop()
trotTrack:Play()
humanoid.WalkSpeed = 20
currentspeed = 20
end

local function playRun()
idleTrack:Stop()
walkTrack:Stop()
trotTrack:Stop()
crouchTrack:Stop()
sneakTrack:Stop()
runTrack:Play()
humanoid.WalkSpeed = 35
currentspeed = 35
end

local function playSneak()
idleTrack:Stop()
walkTrack:Stop()
trotTrack:Stop()
runTrack:Stop()
crouchTrack:Stop()
sneakTrack:Play()
humanoid.WalkSpeed = 6
currentspeed = 6
end

– movement script
uis.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.E then
if emote then
emote = false
playIdle()
elseif currentspeed == 6 then
playWalk()
elseif currentspeed == 12 then
playTrot()
elseif currentspeed == 20 then
playRun()
end
elseif input.KeyCode == Enum.KeyCode.Q then
if emote then
emote = false
playIdle()
elseif currentspeed == 35 then
playTrot()
elseif currentspeed == 20 then
playWalk()
elseif currentspeed == 12 then
playSneak()
end
end
end)

humanoid.Running:Connect(function(speed)
if emote then return end
if currentspeed == 12 then
if speed > 0 then
playWalk()
else
playIdle()
end
elseif currentspeed == 20 then
if speed > 0 then
playTrot()
else
playIdle()
end
elseif currentspeed == 35 then
if speed > 0 then
playRun()
else
playIdle()
end
elseif currentspeed == 6 then
if speed > 0 then
playSneak()
else
playIdle()
end
end
end)

playIdle()

2 Likes

BTW I made a chart to clarify what the script does!!! To reduce confusion!!!


(also sorry if i dont like your post, devforum has a limit to how much you can like within a 24hr span and ive been pretty active lol)

1 Like

In the future please use the code block because I had to tweak almost every single line of code involving variables or comments just to test that this edited script worked.
image
Unfortunately your edited script does not work in the slightest. Sorry. Thank you for trying to help.

1 Like

Hello! I’ve whipped up something pretty quick, that I think will get the job done. Of course, you can alter it how you want and change things, but the core concept is there. If I did all my logic correctly, everything should work fine, but if it doesn’t please let me know! Here’s the script:

--Written by @TechyPlains

--[VARIABLES]----------------------------------------------------------------------------------------------------

--services--
local UIS = game:GetService("UserInputService")
local PLRS = game:GetService("Players")

--main--
local player = PLRS.LocalPlayer
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")

--animations--
local walk_anim = script:WaitForChild("Walk")
local idle_anim = script:WaitForChild("Idle")
local trot_anim = script:WaitForChild("Trot")
local run_anim = script:WaitForChild("Run")
local crouch_anim = script:WaitForChild("Crouch")
local sneak_anim = script:WaitForChild("Sneak")


--animation tracks--
local walk_anim_Track = humanoid.Animator:LoadAnimation(walk_anim)
local sneak_anim_Track = humanoid.Animator:LoadAnimation(sneak_anim)
local crouch_anim_Track = humanoid.Animator:LoadAnimation(crouch_anim)
local run_anim_Track = humanoid.Animator:LoadAnimation(run_anim)
local trot_anim_Track = humanoid.Animator:LoadAnimation(trot_anim)
local idle_anim_Track = humanoid.Animator:LoadAnimation(idle_anim)

--bools--
local isEmoting = false
local isTrotting = false
local isRunning = false
local isSneaking = false
local isCrouching = false

local currentSpeed = 0
local maxSpeed = 100 --you can change this to however high you want
local speed_increase_amount = 1 --you can also change this to be however high you want (goes by WalkSpeed)
local speed_decrease_amount = -1 --you can also change this

--these values are the set values that trigger their corresponding animation and function
--you can change them how you like
local crouchAnimSpeed = 6
local sneakAnimSpeed = 10
local walkAnimSpeed = 16
local runAnimSpeed = 25

--[FUNCTIONS]----------------------------------------------------------------------------------------------------

function animate(toggle)
	if toggle == "walk" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Play()
		idle_anim_Track:Stop()
	elseif toggle == "run" then
		sneak_anim_Track:Stop()
		run_anim_Track:Play()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "trot" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Play()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "crouch" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Play()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "sneak" then
		sneak_anim_Track:Play()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "idle" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Play()
	end
end

--The function that handles inputs from the player
UIS.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.E and not gameProcessed then
		if currentSpeed < maxSpeed then
			currentSpeed += speed_increase_amount
			humanoid.WalkSpeed += speed_increase_amount
		end
	elseif input.KeyCode == Enum.KeyCode.Q and not gameProcessed then
		if currentSpeed > 0 then
			currentSpeed += speed_decrease_amount
			humanoid.WalkSpeed += speed_decrease_amount
		end
	end
end)

humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
	if humanoid.MoveDirection.Magnitude > 0 then
		if isRunning == false and isCrouching == false and isEmoting == false and isSneaking == false and isTrotting == false then
			if walk_anim_Track.IsPlaying == false then
				animate("walk")
			end
		elseif isRunning == false and isCrouching == true and isEmoting == false and isSneaking == false and isTrotting == false then
			if crouch_anim_Track.IsPlaying == false then
				animate("crouch")
			end
		elseif isRunning == false and isCrouching == false and isEmoting == false and isSneaking == true and isTrotting == false then
			if crouch_anim_Track.IsPlaying == false then
				animate("sneak")
			end
		elseif isRunning == false and isCrouching == false and isEmoting == false and isSneaking == false and isTrotting == true then
			if crouch_anim_Track.IsPlaying == false then
				animate("trot")
			end
		elseif isRunning == true then
			if run_anim_Track.IsPlaying == false then
				animate("run")
			end
		end
	else
		if idle_anim_Track.IsPlaying == false then
			animate("idle")
		end
	end
end)

humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
	if currentSpeed <= crouchAnimSpeed then
		isRunning = false
		isSneaking = false
		isEmoting = false
		isTrotting = false
		isCrouching = true
		animate("crouch")
	elseif currentSpeed <= sneakAnimSpeed and currentSpeed > crouchAnimSpeed then
		isRunning = false
		isSneaking = true
		isEmoting = false
		isTrotting = false
		isCrouching = false
		animate("sneak")
	elseif currentSpeed >= walkAnimSpeed and currentSpeed < runAnimSpeed then
		isRunning = false
		isSneaking = false
		isEmoting = false
		isTrotting = false
		isCrouching = false
		animate("walk")
	elseif currentSpeed > walkAnimSpeed and currentSpeed >= runAnimSpeed then
		isRunning = false
		isSneaking = false
		isEmoting = false
		isTrotting = false
		isCrouching = false
		animate("walk")
	end
end)

Like I said above, if there are any issues with it, please let me know. Hopefully this helps!

Cheers,
Techy

1 Like

This doesn’t quite work properly :worried: I’m not sure why since it looks so well organized

So sorry! I completely forgot about some things that I didn’t account for. This should fix the majority of the issues, however since I don’t have actual animations, it’s harder for me to tell. Try this:

--Written by @TechyPlains

--[VARIABLES]----------------------------------------------------------------------------------------------------

--services--
local UIS = game:GetService("UserInputService")
local PLRS = game:GetService("Players")

--main--
local player = PLRS.LocalPlayer
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")

--animations--
local walk_anim = script:WaitForChild("Walk")
local idle_anim = script:WaitForChild("Idle")
local trot_anim = script:WaitForChild("Trot")
local run_anim = script:WaitForChild("Run")
local crouch_anim = script:WaitForChild("Crouch")
local sneak_anim = script:WaitForChild("Sneak")


--animation tracks--
local walk_anim_Track = humanoid.Animator:LoadAnimation(walk_anim)
local sneak_anim_Track = humanoid.Animator:LoadAnimation(sneak_anim)
local crouch_anim_Track = humanoid.Animator:LoadAnimation(crouch_anim)
local run_anim_Track = humanoid.Animator:LoadAnimation(run_anim)
local trot_anim_Track = humanoid.Animator:LoadAnimation(trot_anim)
local idle_anim_Track = humanoid.Animator:LoadAnimation(idle_anim)

--bools--
local isEmoting = false
local isTrotting = false
local isRunning = false
local isSneaking = false
local isCrouching = false

local currentSpeed = 0
local maxSpeed = 100 --you can change this to however high you want
local speed_increase_amount = 1 --you can also change this to be however high you want (goes by WalkSpeed)
local speed_decrease_amount = -1 --you can also change this

--these values are the set values that trigger their corresponding animation and function
--you can change them how you like
local crouchAnimSpeed = 6
local sneakAnimSpeed = 10
local walkAnimSpeed = 16
local runAnimSpeed = 25
local trotAnimSpeed = 13

--[FUNCTIONS]----------------------------------------------------------------------------------------------------

function animate(toggle)
	if toggle == "walk" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Play()
		idle_anim_Track:Stop()
	elseif toggle == "run" then
		sneak_anim_Track:Stop()
		run_anim_Track:Play()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "trot" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Play()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "crouch" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Play()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "sneak" then
		sneak_anim_Track:Play()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Stop()
	elseif toggle == "idle" then
		sneak_anim_Track:Stop()
		run_anim_Track:Stop()
		idle_anim_Track:Stop()
		crouch_anim_Track:Stop()
		trot_anim_Track:Stop()
		walk_anim_Track:Stop()
		idle_anim_Track:Play()
	end
end

--The function that handles inputs from the player
UIS.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.E and not gameProcessed then
		if currentSpeed < maxSpeed then
			currentSpeed += speed_increase_amount
			humanoid.WalkSpeed += speed_increase_amount
		end
	elseif input.KeyCode == Enum.KeyCode.Q and not gameProcessed then
		if currentSpeed > 0 then
			currentSpeed += speed_decrease_amount
			humanoid.WalkSpeed += speed_decrease_amount
		end
	end
end)

humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
	if humanoid.MoveDirection.Magnitude > 0 then
		if isRunning == false and isCrouching == false and isEmoting == false and isSneaking == false and isTrotting == false then
			if walk_anim_Track.IsPlaying == false then
				animate("walk")
			end
		elseif isRunning == false and isCrouching == true and isEmoting == false and isSneaking == false and isTrotting == false then
			if crouch_anim_Track.IsPlaying == false then
				animate("crouch")
			end
		elseif isRunning == false and isCrouching == false and isEmoting == false and isSneaking == true and isTrotting == false then
			if crouch_anim_Track.IsPlaying == false then
				animate("sneak")
			end
		elseif isRunning == false and isCrouching == false and isEmoting == false and isSneaking == false and isTrotting == true then
			if crouch_anim_Track.IsPlaying == false then
				animate("trot")
			end
		elseif isRunning == true then
			if run_anim_Track.IsPlaying == false then
				animate("run")
			end
		end
	else
		if idle_anim_Track.IsPlaying == false then
			animate("idle")
		end
	end
end)

humanoid:GetPropertyChangedSignal("WalkSpeed"):Connect(function()
	if humanoid.MoveDirection.Magnitude > 0 then
		if currentSpeed <= crouchAnimSpeed then
			isRunning = false
			isSneaking = false
			isEmoting = false
			isTrotting = false
			isCrouching = true
			if crouch_anim_Track.IsPlaying == false then
				animate("crouch")
			end
		elseif currentSpeed <= sneakAnimSpeed and currentSpeed > crouchAnimSpeed then
			isRunning = false
			isSneaking = true
			isEmoting = false
			isTrotting = false
			isCrouching = false
			if crouch_anim_Track.IsPlaying == false then
				animate("sneak")
			end
		elseif currentSpeed <= walkAnimSpeed and currentSpeed > crouchAnimSpeed and currentSpeed > sneakAnimSpeed then
			isRunning = false
			isSneaking = false
			isEmoting = false
			isTrotting = true
			isCrouching = false
			if crouch_anim_Track.IsPlaying == false then
				animate("trot")
			end
		elseif currentSpeed >= walkAnimSpeed and currentSpeed < runAnimSpeed then
			isRunning = false
			isSneaking = false
			isEmoting = false
			isTrotting = false
			isCrouching = false
			if walk_anim_Track.IsPlaying == false then
				animate("walk")
			end
		elseif currentSpeed > walkAnimSpeed and currentSpeed >= runAnimSpeed then
			isRunning = true
			isSneaking = false
			isEmoting = false
			isTrotting = false
			isCrouching = false
			if run_anim_Track.IsPlaying == false then
				animate("run")
			end
		end
	else
		animate("idle")
	end
end)

Sorry for the inconvenience!

1 Like

No I’m the one sorry for the inconvenience, I’ve got you out here remaking 99% of the code haha. I’m 100% gonna credit you when this all works out.
But right now it’s still not working and I really don’t know why, I’m sorry lol :sweat_smile:
Clip of gameplay (file too large so link) https://www.youtube.com/watch?v=wL1KzeVLkJg

I tried to simplify to the best of my ability:

local UserInputService = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:FindFirstChild("Humanoid")

-- movement tracks
local animations = {
	walk = script:WaitForChild("Walk"),
	idle = script:WaitForChild("Idle"),
	trot = script:WaitForChild("Trot"),
	run = script:WaitForChild("Run"),
	crouch = script:WaitForChild("Crouch"),
	sneak = script:WaitForChild("Sneak"),
}

for animationName, animation in animations do
	animations[animationName] = humanoid.Animator:LoadAnimation(animation)
end

local emotes = {
	sit = script:WaitForChild("Sit"),
	--add more if you want
}
for animationName, animation in emotes do
	emotes[animationName] = humanoid.Animator:LoadAnimation(animation)
end

-- task identifiers
local emoting = false
local currentIndex = 2 --walk
local states = {
	{
		type = "sneak",
		speed = 6,
	},
	{
		type = "walk",
		speed = 12,
	},
	{
		type = "trot",
		speed = 20,
	},
	{
		type = "run",
		speed = 35,
	},
}

-- movement script
UserInputService.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end

	if emoting then
		return
	end

	if input == Enum.KeyCode.Q then
		currentIndex -= 1
	elseif input == Enum.KeyCode.E then
		currentIndex += 1
	end

	currentIndex = math.clamp(currentIndex, 1, #states)
end)

humanoid.Running:Connect(function(speed)
	for _, animation in animations do
		animation:Stop()
	end

	if emoting then
		return
	end

	local state = states[currentIndex]
	local animation = animations[state.type]

	if speed <= 0 then
		if state.type == "sneak" then
			animations.crouch:Play()
			return
		end
		animations.idle:Play()
		return
	end

	humanoid.WalkSpeed = state.speed
	animation:Play()
end)

animations.idle:Play()

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

	if input.KeyCode == Enum.KeyCode.R then
		if not emoting then
			emotes.sit:Play()
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
		else
			emotes.sit:Stop()
			local state = states[currentIndex]
			humanoid.WalkSpeed = state.speed
			humanoid.JumpPower = 35
		end

		emoting = not emoting
	end
end)

1 Like

This edited script contains a fix for the following:

  • Major animation bugging when turning.

The following issues are still present:

  • Animation bugs when climbing slope and very high or very low speed turns.
  • Script is messy and fragile and leaves no room for flight animations.

How movement looks now: https://youtu.be/tGBfyxh7QIY

Edited script:

local uis = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:FindFirstChild("Humanoid")


-- movement tracks
local walk = script:WaitForChild("Walk")
local walkTrack = humanoid.Animator:LoadAnimation(walk)
local idle = script:WaitForChild("Idle")
local idleTrack = humanoid.Animator:LoadAnimation(idle)
local trot = script:WaitForChild("Trot")
local trotTrack = humanoid.Animator:LoadAnimation(trot)
local run = script:WaitForChild("Run")
local runTrack = humanoid.Animator:LoadAnimation(run)
local crouch = script:WaitForChild("Crouch")
local crouchTrack = humanoid.Animator:LoadAnimation(crouch)
local sneak = script:WaitForChild("Sneak")
local sneakTrack = humanoid.Animator:LoadAnimation(sneak)

-- task identifiers
local emote = false
local speedwalk = true
local speedtrot = false
local speedrun = false
local speedsneak = false
local currentspeed = false

-- movement script

uis.InputBegan:Connect(function(input, gpe)
	if gpe then return end
	if input.KeyCode == Enum.KeyCode.E and speedsneak == true then -- begin walking
		speedwalk = true
		speedsneak = false
		
		speedtrot = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.E and speedwalk == true then -- begin trotting
		speedwalk = false
		speedtrot = true
		
		speedsneak = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.E and speedtrot == true then -- begin running
		speedtrot = false
		speedrun = true
		
		speedsneak = false
		speedwalk = false
	elseif input.KeyCode == Enum.KeyCode.Q and speedrun == true then -- slow to trot
		speedrun = false
		speedtrot = true
		
		speedsneak = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.Q and speedtrot == true then -- slow to walk
		speedtrot = false
		speedwalk = true
		
		speedsneak = false
		speedrun = false
	elseif input.KeyCode == Enum.KeyCode.Q and speedwalk == true then -- slow to sneak
		speedwalk = false
		speedsneak = true
		
		speedtrot = false
		speedrun = false
	end
end)

humanoid.Running:Connect(function(speed)
	if speedwalk == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		local animationplaying = false
		walkTrack.Stopped:Connect(function()
			animationplaying = false
		end)
		if speed > 0 and emote == false then
			if animationplaying == true then return end
			if animationplaying == false then
				idleTrack:Stop()
				walkTrack:Play()
				humanoid.WalkSpeed = 12
				currentspeed = 12
			end
		elseif emote == false then
			idleTrack:Play()
			walkTrack:Stop()
		end
	end
	if speedtrot == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		local animationplaying = false
		trotTrack.Stopped:Connect(function()
			animationplaying = false
		end)
		if speed > 0 and emote == false then
			if animationplaying == true then return end
			if animationplaying == false then
				idleTrack:Stop()
				trotTrack:Play()
				humanoid.WalkSpeed = 20
				currentspeed = 20
			end
		elseif emote == false then
			idleTrack:Play()
			trotTrack:Stop()
		end
	end
	if speedrun == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		local animationplaying = false
		runTrack.Stopped:Connect(function()
			animationplaying = false
		end)
		if speed > 0 and emote == false then
			if animationplaying == true then return end
			if animationplaying == false then
				idleTrack:Stop()
				runTrack:Play()
				humanoid.WalkSpeed = 35
				currentspeed = 35
			end
		elseif emote == false then
			idleTrack:Play()
			runTrack:Stop()
		end
	end
	if speedsneak == true then
		walkTrack:Stop()
		idleTrack:Stop()
		trotTrack:Stop()
		runTrack:Stop()
		crouchTrack:Stop()
		sneakTrack:Stop()
		local animationplaying = false
		sneakTrack.Stopped:Connect(function()
			animationplaying = false
		end)
		if speed > 0 and emote == false then
			if animationplaying == true then return end
			if animationplaying == false then
				crouchTrack:Stop()
				sneakTrack:Play()
				humanoid.WalkSpeed = 6
				currentspeed = 6
			end
		elseif emote == false then
			crouchTrack:Play()
			sneakTrack:Stop()
		end
	end
end)

idleTrack:Play()

-- END OF MOVEMENTS

-- EMOTES

-- EMOTE LIST
local sit = script:WaitForChild("Sit")
local sitTrack = humanoid.Animator:LoadAnimation(sit)

uis.InputBegan:Connect(function(input, gpe)
	if gpe then return end
	if input.KeyCode == Enum.KeyCode.R then
		if emote == false then
			emote = true
			sitTrack:Play()
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
			print("now sitting")
		else
			emote = false
			sitTrack:Stop()
			humanoid.WalkSpeed = currentspeed
			humanoid.JumpPower = 35
			print("now unsitting")
		end
	end
end)

While the script you’ve written does appear more organized, pressing Q and E does not function. Only sitting seems to work properly. Sorry.

if was because I used input instead of input.KeyCode
My bad.
Here’s a fixed version:

local UserInputService = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:FindFirstChild("Humanoid")

-- movement tracks
local animations = {
	walk = script:WaitForChild("Walk"),
	idle = script:WaitForChild("Idle"),
	trot = script:WaitForChild("Trot"),
	run = script:WaitForChild("Run"),
	crouch = script:WaitForChild("Crouch"),
	sneak = script:WaitForChild("Sneak"),
}


local emotes = {
	sit = script:WaitForChild("Sit"),
	--add more if you want
}

for animationName, animation in animations do
	animations[animationName] = humanoid.Animator:LoadAnimation(animation)
end
for animationName, animation in emotes do
	emotes[animationName] = humanoid.Animator:LoadAnimation(animation)
end

-- task identifiers
local emoting = false
local currentIndex = 2 --walk
local states = {
	{ type = "sneak", speed = 6 },
	{ type = "walk", speed = 12 },
	{ type = "trot", speed = 20 },
	{ type = "run", speed = 35 },
}

local function updateIdleAnimation(state)
	for _, animation in animations do
		animation:Stop()
	end

	if humanoid.MoveDirection.Magnitude ~= 0 then
		return
	end

	if state.type == "sneak" then
		animations.crouch:Play()
		return
	end

	animations.idle:Play()
end
-- movement script
UserInputService.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end

	if emoting then
		return
	end

	if input.KeyCode == Enum.KeyCode.Q then
		if currentIndex == 1 then
			return
		end
		currentIndex -= 1
	elseif input.KeyCode == Enum.KeyCode.E then
		if currentIndex == #states then
			return
		end
		currentIndex += 1
	else
		return
	end

	currentIndex = math.clamp(currentIndex, 1, #states)
	local state = states[currentIndex]
	humanoid.WalkSpeed = state.speed

	updateIdleAnimation(state)
end)

humanoid.Running:Connect(function(speed)
	if emoting then
		return
	end

	local state = states[currentIndex]
	local animation = animations[state.type]

	updateIdleAnimation(state)

	if speed <= 0 then
		return
	end

	humanoid.WalkSpeed = state.speed
	animation:Play()
end)

animations.idle:Play()

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

	if input.KeyCode == Enum.KeyCode.R then
		if not emoting then
			emotes.sit:Play()
			humanoid.WalkSpeed = 0
			humanoid.JumpPower = 0
		else
			emotes.sit:Stop()
			local state = states[currentIndex]
			humanoid.WalkSpeed = state.speed
			humanoid.JumpPower = 35
		end

		emoting = not emoting
	end
end)
1 Like