Animations overlaping

I used the default Animate script from Roblox to play my custom animations, and alongside that, I added a local script for handling the sprint, crouch, and crawl animations. Some of the animations also have an event named “Step,” so I can also play a sound for each step. The only problem is that the walk animations overlap, so it detects both keyframe events, thus playing the sound repeatedly

Here’s the code that I made for the sprint, crouch, and crawl

Code
--// Services
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")


--// Player
local Player = game.Players.LocalPlayer
local Character = Player.Character
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")


--// Character States
local StateFolder = Player:WaitForChild("CharacterState")
local IsMoving = StateFolder:WaitForChild("IsMoving")
local IsSprinting = StateFolder:WaitForChild("IsSprinting")
local IsCrouching = StateFolder:WaitForChild("IsCrouching")
local IsCrawling = StateFolder:WaitForChild("IsCrawling")


--// Walkspeed
local CharRef = Player:WaitForChild("CharacterReferences")
local DefaultSpeed = CharRef:WaitForChild("DefaultSpeed")
local SprintSpeed = CharRef:WaitForChild("SprintSpeeed")
local CrouchSpeed = CharRef:WaitForChild("CrouchSpeed")
local CrawlSpeed = CharRef:WaitForChild("CrawlSpeed")


--// Animations
local SprintAnim = script:WaitForChild("run"):WaitForChild("RunAnim")
local CrouchIdleAnim = script:WaitForChild("crouch"):WaitForChild("CrouchIdleAnim")
local CrouchWalkAnim = script:WaitForChild("crouch"):WaitForChild("CrouchWalkAnim")
local CrawlIdleAnim = script:WaitForChild("crawl"):WaitForChild("CrawlIdleAnim")
local CrawlWalkAnim = script:WaitForChild("crawl"):WaitForChild("CrawlWalkAnim")

local SprintAnimTrack = Animator:LoadAnimation(SprintAnim)
local CrouchIdleAnimTrack = Animator:LoadAnimation(CrouchIdleAnim)
local CrouchWalkAnimTrack = Animator:LoadAnimation(CrouchWalkAnim)
local CrawlIdleAnimTrack = Animator:LoadAnimation(CrawlIdleAnim)
local CrawlWalkAnimTrack = Animator:LoadAnimation(CrawlWalkAnim)


--// Keybinds
local SprintBind = Enum.KeyCode.LeftShift
local CrouchCrawlBind = Enum.KeyCode.C


--// Keybind States
local CrouchCrawlIndex = 0 -- 0 = Standing, 1 = Crouching, 2 = Crawling
local CrouchCrawlDebounce = false
local SprintDown = false

local PressDebounce = false


--// Sprint References
local SprintRef = Player:WaitForChild("SprintReference")
local MaxStamina = SprintRef:WaitForChild("MaxStamina")
local StaminaUsage = SprintRef:WaitForChild("StaminaUsage")
local Stamina = SprintRef:WaitForChild("Stamina")

--// State Handler
UserInputService.InputBegan:Connect(function(input, gp)
	if gp then return end

	if input.KeyCode == CrouchCrawlBind and PressDebounce == false then
		if not CrouchCrawlDebounce then
			CrouchCrawlDebounce = true
			PressDebounce = true

			if CrouchCrawlIndex == 0 then
				CrouchCrawlIndex = 1
				IsCrouching.Value = true
				IsCrawling.Value = false

			elseif CrouchCrawlIndex == 1 then
				CrouchCrawlIndex = 2
				IsCrouching.Value = false
				IsCrawling.Value = true

			elseif CrouchCrawlIndex == 2 then
				CrouchCrawlIndex = 0
				IsCrouching.Value = false
				IsCrawling.Value = false
			end
			
			CrouchCrawlDebounce = false
			PressDebounce = false
		end

	elseif input.KeyCode == SprintBind and PressDebounce == false then
		PressDebounce = true
		
		CrouchCrawlIndex = 0
		IsCrouching.Value = false
		IsCrawling.Value = false

		SprintDown = true
		IsSprinting.Value = IsMoving.Value
	end
end)

UserInputService.InputEnded:Connect(function(input, gp)
	if gp then return end

	if input.KeyCode == SprintBind then
		PressDebounce = false
		SprintDown = false
		IsSprinting.Value = false
	end
end)
RunService.RenderStepped:Connect(function()
	local isMovingNow = Humanoid.MoveDirection.Magnitude > 0
	IsMoving.Value = isMovingNow

	if SprintDown and isMovingNow and Stamina.Value > 0 then
		IsSprinting.Value = true
	else
		IsSprinting.Value = false
	end
end)


--// Animations Handler

local function UpdateState()

	if IsSprinting.Value then
		Humanoid.WalkSpeed = SprintSpeed.Value

		CrouchIdleAnimTrack:Stop()
		CrouchWalkAnimTrack:Stop()
		CrawlIdleAnimTrack:Stop()
		CrawlWalkAnimTrack:Stop()

		SprintAnimTrack:Play()
		return
	else
		SprintAnimTrack:Stop()
	end

	CrouchIdleAnimTrack:Stop()
	CrouchWalkAnimTrack:Stop()
	CrawlIdleAnimTrack:Stop()
	CrawlWalkAnimTrack:Stop()

	if IsCrouching.Value then
		Humanoid.WalkSpeed = CrouchSpeed.Value
		if IsMoving.Value then
			CrouchWalkAnimTrack:Play()
		else
			CrouchIdleAnimTrack:Play()
		end

	elseif IsCrawling.Value then
		Humanoid.WalkSpeed = CrawlSpeed.Value
		if IsMoving.Value then
			CrawlWalkAnimTrack:Play()
		else
			CrawlIdleAnimTrack:Play()
		end

	else
		Humanoid.WalkSpeed = DefaultSpeed.Value
	end
end

for i, State in pairs(StateFolder:GetChildren()) do
	if State:IsA("ValueBase") then
		State.Changed:Connect(UpdateState)
	end
end


--// Sprint Handler
local lastSprint = math.huge

RunService.RenderStepped:Connect(function()
	
	if Stamina.Value < StaminaUsage.Value then
		IsSprinting.Value = false
		SprintDown = false
	end
	
	if IsSprinting.Value == true and IsMoving.Value == true and Stamina.Value > 0 then
		Stamina.Value = Stamina.Value - StaminaUsage.Value
		lastSprint = tick()
	else
		if tick() - lastSprint >= 1 and Stamina.Value < MaxStamina.Value then
			Stamina.Value = Stamina.Value + StaminaUsage.Value
		end
	end
end)


--// Footstep Sounds
local LeftSound = script.Left
local RightSound = script.Right

local SoundIndex = 0 -- 0 = left, 1 = right

Humanoid.AnimationPlayed:Connect(function(track)
	print(track.Name) --where I found out that the animations are overlaping
end)

the only solution I have in mind is to merge this with the default Animate script, but I dont know where and how to start that

Can you like set higher priority for animation you need?
If they both have same priority they are just gonna blend and result may be strange.

I have set the priorities, and the animations look fine, it’s just that the keyframe events overlap.