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)
--\\