Making my own movement script need help

For the most part the directional movement works well. However the falling animation seems to play on loop if I jump in place. It also seems the falling animation doesn’t play when falling from height if the character is moving. This is my first time attempting to create a script like this so I’m not sure what I am doing wrong?

--// SERVICES
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
--\\

--// VARIABLES
local Player = Players.LocalPlayer
local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local Animator = Humanoid:WaitForChild("Animator")
local MovementInputChanged = script:WaitForChild("MovementInputChanged")

local LastFootstepSound = nil
local TransitionTime = 0.2
local JumpAnimTime = 0
local Movement = "Run"
local RelativeSpeed = 0
local WalkAnimWeight, RunAnimWeight, SprintAnimWeight = 0.001, 0.001, 0.001

local CurrentMovementDirection = Vector3.zero
local MovementDirections = {
	[Vector3.zero] = "Idle",
	[Vector3.new(0, 0, 1)] = "Backward",
	[Vector3.new(-1, 0, 1)] = "BackwardLeft",
	[Vector3.new(1, 0, 1)] = "BackwardRight",
	[Vector3.new(0, 0, -1)] = "Forward",
	[Vector3.new(-1, 0, -1)] = "ForwardLeft",
	[Vector3.new(1, 0, -1)] = "ForwardRight",
	[Vector3.new(1, 0, 0)] = "Right",
	[Vector3.new(-1, 0, 0)] = "Left"
}

local AnimationIds = {
	Climb = "rbxassetid://140342194662037",
	Fall = "rbxassetid://105495597781535",
	Idle = "rbxassetid://104734710598531",
	Jump = "rbxassetid://136558857657886",
	RunForward = "rbxassetid://134372235241315",
	RunBackward = "rbxassetid://135225627130387",
	RunBackwardLeft = "rbxassetid://83321189162121",
	RunBackwardRight = "rbxassetid://105763798965188",
	RunForwardLeft = "rbxassetid://71028281638765",
	RunForwardRight = "rbxassetid://125253375126672",
	RunLeft = "rbxassetid://87424756600811",
	RunRight = "rbxassetid://113184506154201",
	WalkForward = "rbxassetid://110000932236990",
	WalkBackward = "rbxassetid://133373623347034",
	WalkBackwardLeft = "rbxassetid://104023573970105",
	WalkBackwardRight = "rbxassetid://137131996576180",
	WalkForwardLeft = "rbxassetid://84255850021254",
	WalkForwardRight = "rbxassetid://118389532422054",
	WalkLeft = "rbxassetid://106835859150869",
	WalkRight = "rbxassetid://125246062024323",
	Sprint = "rbxassetid://70803976418386",
	Swim = "rbxassetid://10921264784",
	SwimIdle = "rbxassetid://10921265698"
}
local LoadedAnimations = {}
local CurrentMovementAnimation = nil
--\\

--// MODULES
--local Footsteps = require(script:WaitForChild("Footsteps"))
local Input = require(script:WaitForChild("Input"))
--\\

--// LOCAL FUNCTIONS
local function StopAllAnimations(IgnoreName)
	for _, AnimTrack in pairs(Animator:GetPlayingAnimationTracks()) do
		if (AnimTrack.Name == IgnoreName)
			or (IgnoreName == "Run" .. MovementDirections[CurrentMovementDirection]) and (AnimTrack.Name == "Walk" .. MovementDirections[CurrentMovementDirection])
			or (IgnoreName == "Sprint") and (AnimTrack.Name == "Run" .. MovementDirections[CurrentMovementDirection])
			or (IgnoreName == "Sprint") and (AnimTrack.Name == "Walk" .. MovementDirections[CurrentMovementDirection]) then
			continue
		end
		AnimTrack:Stop(TransitionTime)
	end
end

local function AdjustAnimation(Name, Speed, Weight)
	LoadedAnimations[Name]:AdjustSpeed(Speed)
	LoadedAnimations[Name]:AdjustWeight(Weight)
end

local function PlayAnimation(Name, Speed, Weight)
	LoadedAnimations[Name]:Play(TransitionTime)
	AdjustAnimation(Name, Speed, Weight)
	StopAllAnimations(Name)
end

local function MovementAnimationChange(State)
	if (State == Enum.HumanoidStateType.Jumping) then return end
	if (Humanoid:GetState() == Enum.HumanoidStateType.Freefall) then return end
	if (Humanoid:GetState() == Enum.HumanoidStateType.Climbing) then return end
	if (State == Enum.HumanoidStateType.Landed) then return end
	if (MovementDirections[CurrentMovementDirection] ~= "Idle") and (LoadedAnimations[Movement .. MovementDirections[CurrentMovementDirection]].IsPlaying) then
		AdjustAnimation("Walk" .. MovementDirections[CurrentMovementDirection], RelativeSpeed, WalkAnimWeight)
		AdjustAnimation("Run" .. MovementDirections[CurrentMovementDirection], RelativeSpeed, RunAnimWeight)
		AdjustAnimation("Sprint", RelativeSpeed, SprintAnimWeight)
	else
		for Vector, Direction in (MovementDirections) do
			if (CurrentMovementDirection == Vector) then
				if (CurrentMovementAnimation ~= nil) then
					CurrentMovementAnimation:Stop()
				end
				if (Direction == "Idle") then
					CurrentMovementAnimation = LoadedAnimations[Direction]
					PlayAnimation(CurrentMovementAnimation.Name, RelativeSpeed, 1)
				else
					CurrentMovementAnimation = LoadedAnimations[Movement .. Direction]
					PlayAnimation("Walk" .. Direction, RelativeSpeed, WalkAnimWeight)
					PlayAnimation("Run" .. Direction, RelativeSpeed, RunAnimWeight)
					PlayAnimation("Sprint", RelativeSpeed, SprintAnimWeight)
				end
				--CurrentMovementAnimation:Play()
				--PlayAnimation(CurrentMovementAnimation.Name, RelativeSpeed, 1)
				--PlayAnimation(CurrentMovementAnimation.Name, RelativeSpeed, 1)
			end
		end
	end
end

local function CardinalConvert(Direction, MultiDirectional)
	local NewMultiDirectional = MultiDirectional or false
	local Angle = math.atan2(Direction.X, -Direction.Z)
	local QuarterTurn
	if (NewMultiDirectional) then
		QuarterTurn = math.pi / 4
	else
		QuarterTurn = math.pi / 2
	end
	if (Direction == Vector3.zero) then return Vector3.zero end
	Angle = -math.round(Angle / QuarterTurn) * QuarterTurn
	local NewX = math.round(-math.sin(Angle))
	local NewZ = math.round(-math.cos(Angle))
	if (math.abs(NewX) <= 1e-10) then NewX = 0 end
	if (math.abs(NewZ) <= 1e-10) then NewZ = 0 end
	return Vector3.new(NewX, 0, NewZ)
end

local function MovementDirectionChanged(MovementInput)
	CurrentMovementDirection = CardinalConvert(MovementInput, true)
	MovementAnimationChange()
end

local function Running(Speed)
	if (Speed > 0.5) then
		RelativeSpeed = Speed / 16
		WalkAnimWeight, RunAnimWeight, SprintAnimWeight = 0.001, 0.001, 0.001
		
		if (RelativeSpeed < 0.7) then
			--Walk
			Movement = "Walk"
			WalkAnimWeight = 1
			if (MovementDirections[CurrentMovementDirection] == "Forward") then
				RelativeSpeed += 0.3
			end
		elseif (RelativeSpeed < 0.9) then
			WalkAnimWeight = 0.25
			RunAnimWeight = 0.75
		elseif (RelativeSpeed <= 1) then
			--Run
			Movement = "Run"
			RunAnimWeight = 1
		else
			SprintAnimWeight = 1
		end
		
		MovementAnimationChange()
	else
		RelativeSpeed = 0
	end
end

local function Jumping()
	JumpAnimTime = 0.31
	PlayAnimation("Jump")
end

local function Falling()
	if (JumpAnimTime <= 0) then
		PlayAnimation("Fall")
	end
end

local function Climbing(Speed)
	if (Speed == 0) then
		if (MovementDirections[CurrentMovementDirection] == "Idle") then
			AdjustAnimation("Climb", 0, 1)
		end
	else
		local RelativeSpeed = Speed / 5
		if (LoadedAnimations["Climb"].IsPlaying) then
			AdjustAnimation("Climb", RelativeSpeed, 1)
		else
			PlayAnimation("Climb", RelativeSpeed)
		end
	end
end

local function Swimming(Speed)
	if (Speed > 1) then
		local RelativeSpeed = Speed / 10

		if (LoadedAnimations["Swim"].IsPlaying) then
			AdjustAnimation("Swim", RelativeSpeed, 1)
		else
			PlayAnimation("Swim", RelativeSpeed)
		end
	elseif not(LoadedAnimations["SwimIdle"].IsPlaying) then
		PlayAnimation("SwimIdle", 1)
	end
end

local function LoadAnimations()
	for Name, Id in pairs(AnimationIds) do
		local Animation = Instance.new("Animation", script.Animations)
		Animation.Name = Name
		Animation.AnimationId = Id

		local Track = Animator:LoadAnimation(Animation)
		LoadedAnimations[Name] = Track
		LoadedAnimations[Name].Name = Name

		if (Name == "Idle") then
			LoadedAnimations[Name].Priority = Enum.AnimationPriority.Idle
		elseif (Name == "RunForward") or (Name == "WalkForward") or (Name == "Sprint") or (Name == "Climb") then
			LoadedAnimations[Name].Priority = Enum.AnimationPriority.Movement
		elseif (Name == "Tool") or (Name == "Jump") then
			LoadedAnimations[Name].Priority = Enum.AnimationPriority.Action
		end
	end
	CurrentMovementAnimation = LoadedAnimations["Idle"]
	PlayAnimation("Idle")
	
	Humanoid.Running:Connect(Running)
	Humanoid.Jumping:Connect(Jumping)
	Humanoid.FallingDown:Connect(Jumping)
	Humanoid.FreeFalling:Connect(Falling)
	Humanoid.Climbing:Connect(Climbing)
	Humanoid.Swimming:Connect(Swimming)
	Humanoid.StateChanged:Connect(MovementAnimationChange)
	MovementInputChanged.Event:Connect(MovementDirectionChanged)
end
LoadAnimations()
--\\

--// RUNTIME
RunService.Heartbeat:Connect(function(DeltaTime)
	if (JumpAnimTime > 0) then
		JumpAnimTime = JumpAnimTime - DeltaTime
	end
	Input.Update(DeltaTime)
end)
--\\
1 Like

Hi, @Vyvorr.

You could just make animation fall have higher authority or if falling then don’t play animation walk or run

1 Like

Hi, I just tried giving the falling animation a higher priority and also stopped walk/run animations from running if the humanoid is in a free fall state however this didn’t work. It seems if I run off a ledge the free fall animation works but if I jump off a ledge it doesn’t work when the jump animation finishes?

Have you tried replacing the default fall animation under ‘Animate’ to your desired animation?

I have replaced it with a custom one. This script is my own custom Animate script so I’m not sure what I’m doing wrong to trigger free fall animation after a jump. It plays when walking off a ledge just not from jumping