Player doesn't leave the falling state after jumping

  1. I want to achieve a custom moveset with animations.

  2. The issue is that the player does not leave the falling action after jumping.

  1. I have tried looking for help in various developer discords, and I’ve googled. I have rewritten it about 3 times and cannot figure out the probelm.
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local player = Players.LocalPlayer
local mouse = player:GetMouse()
local camera = workspace.CurrentCamera
local headTiltEvent = ReplicatedStorage:WaitForChild("HeadTiltEvent")

local char = player.Character or player.CharacterAdded:Wait()
local head = char:WaitForChild("Head")
local torso = char:WaitForChild("Torso")
local neck = torso:WaitForChild("Neck")
local humanoid = char:WaitForChild("Humanoid")
local root = char:WaitForChild("HumanoidRootPart")

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {char}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist

local function isGrounded()
	local origin = root.Position
	local direction = Vector3.new(0, -3, 0)
	local raycastResult = workspace:Raycast(origin, direction, raycastParams)
	return raycastResult ~= nil
end

local function SetCharacterLocalTransparency(transparency)
	for _, v in pairs(char:GetDescendants()) do
		if v:IsA("BasePart") or v:IsA("MeshPart") then
			local isInAccessory = false
			local ancestor = v.Parent
			while ancestor and ancestor ~= char do
				if ancestor:IsA("Accessory") then
					isInAccessory = true
					break
				end
				ancestor = ancestor.Parent
			end

			if v.Name ~= "Head" and v.Name ~= "Torso" and not isInAccessory then
				v.LocalTransparencyModifier = transparency
			end
		end
	end
end

local neckStart = neck.C0
neck.MaxVelocity = 1 / 3

local walkSpeed = 8
local sprintSpeed = 32
local accelTime = 0.25

local isRunning = false
local accelerating = false
local lastMove = 0
local isJumping = false
local isFalling = false

local runAnim = Instance.new("Animation")
local jumpAnim = Instance.new("Animation")
local fallAnim = Instance.new("Animation")
runAnim.AnimationId = "rbxassetid://133623211953325"
jumpAnim.AnimationId = "rbxassetid://85940942685577"
fallAnim.AnimationId = "rbxassetid://83122401812651"

local animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator")
animator.Parent = humanoid

local runTrack = animator:LoadAnimation(runAnim)
runTrack.Priority = Enum.AnimationPriority.Movement
local jumpTrack = animator:LoadAnimation(jumpAnim)
jumpTrack.Priority = Enum.AnimationPriority.Action
local fallTrack = animator:LoadAnimation(fallAnim)
fallTrack.Priority = Enum.AnimationPriority.Action

local function onCharacterAdded(newChar)
	char = newChar
	root = char:WaitForChild("HumanoidRootPart")
	humanoid = char:WaitForChild("Humanoid")
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Running, false)
	head = char:WaitForChild("Head")
	torso = char:WaitForChild("Torso")
	neck = torso:WaitForChild("Neck")

	animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator")
	animator.Parent = humanoid

	if runTrack then runTrack:Stop() end
	if jumpTrack then jumpTrack:Stop() end
	if fallTrack then fallTrack:Stop() end

	runTrack = animator:LoadAnimation(runAnim)
	runTrack.Priority = Enum.AnimationPriority.Movement
	jumpTrack = animator:LoadAnimation(jumpAnim)
	jumpTrack.Priority = Enum.AnimationPriority.Action
	fallTrack = animator:LoadAnimation(fallAnim)
	fallTrack.Priority = Enum.AnimationPriority.Action

	neckStart = neck.C0
	isJumping = false
	isFalling = false
	SetCharacterLocalTransparency(0.6)
end

player.CharacterAdded:Connect(onCharacterAdded)
if player.Character then onCharacterAdded(player.Character) end

local function accelerate()
	if accelerating then return end
	accelerating = true
	local start = tick()

	while tick() - start < accelTime and isRunning do
		local t = math.clamp((tick() - start) / accelTime, 0, 1)
		humanoid.WalkSpeed = walkSpeed + (sprintSpeed - walkSpeed) * t
		runTrack:AdjustSpeed(0.8 + t * 0.5)
		RunService.RenderStepped:Wait()
	end

	if isRunning then
		humanoid.WalkSpeed = sprintSpeed
		runTrack:AdjustSpeed(1.3)
	end

	accelerating = false
end

humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Jumping then
		isJumping = true
		isFalling = false
		if runTrack.IsPlaying then
			runTrack:Stop(0.1)
		end
		jumpTrack:Play()
		fallTrack:Stop()
	elseif newState == Enum.HumanoidStateType.Freefall then
		if isJumping then
			isFalling = true
			fallTrack:Play()
			jumpTrack:Stop()
		end
	elseif newState == Enum.HumanoidStateType.Landed then
		isJumping = false
		isFalling = false
		jumpTrack:Stop(0.1)
		fallTrack:Stop(0.1)
		if isRunning and humanoid.MoveDirection.Magnitude > 0.1 then
			task.wait(0.1)
			if humanoid:GetState() ~= Enum.HumanoidStateType.Jumping then
				runTrack:Play()
			end
		end
	elseif newState == Enum.HumanoidStateType.Running then
		if not isJumping and not isFalling then
			isJumping = false
			isFalling = false
			jumpTrack:Stop(0.1)
			fallTrack:Stop(0.1)
		end
	end
end)

RunService.RenderStepped:Connect(function()
	SetCharacterLocalTransparency(0.6)
	local moving = humanoid.MoveDirection.Magnitude > 0.1

	if isFalling and isGrounded() then
		isFalling = false
		fallTrack:Stop(0.1)
	end

	if moving then
		lastMove = tick()
		if not isRunning and not isJumping and not isFalling then
			isRunning = true
			runTrack:Play()
			runTrack:AdjustSpeed(0.8)
			accelerate()
		end
	elseif isRunning and tick() - lastMove > 0.1 then
		isRunning = false
		humanoid.WalkSpeed = walkSpeed
		runTrack:Stop(0.1)
	end

	if char:FindFirstChild("Torso") and char:FindFirstChild("Head") then
		if camera.CameraSubject:IsDescendantOf(char) then
			local target = mouse.Hit.p
			local dir = (target - head.Position).Unit
			local pitch = math.clamp(-math.asin(dir.Y), -0.75, 0.75) * 0.7
			local angle = CFrame.Angles(pitch, 0, 0)
			headTiltEvent:FireServer(angle)
		end
	end
end)