So I wanted to add some custom animations for my game, and I had planned to do an animation for hitting the ground when falling beyond a certain distance with the default Animate script, but even though I could get the animation to play by changing the Freefall function to as follows
function onFreeFall()
if (jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
end
pose = "FreeFall"
--[[Humanoid.StateChanged:Connect(function(old, new)
if old == Enum.HumanoidStateType.Freefall and new == Enum.HumanoidStateType.Landed then
if currentAnimInstance and currentAnimInstance.Name == "FallAnim" then
playAnimation("land", 0.1, Humanoid)
pose = "Landed"
end
end
end)]]
end
(noted out parts are the landing animation which did work)
However, because I did it like this, it uses the default function of the Animate script
playAnimation(“animID”, fadingTime, humanoid)
and I can’t adjust the speed with this. The animation plays too quickly for some reason and I’m unsure how to change this and how I would check how far a player has fallen since I don’t want this animation to play whenever they jump 10cm.
yo, so there are many ways but one of the easy ways of doing it can be getting how much time has passed since the player jumped or is free falling
local free_fall_Time = 1 -- time it takes to play the fall animation
local Track_Time = tick() -- sets the tick
Humanoid.StateChanged:Connect(function(_, STATE)
if STATE == Enum.HumanoidStateType.Jumping or STATE == Enum.HumanoidStateType.Freefall then
Track_Time = Tick()
elseif Humanoid:GetState() ~= Enum.HumanoidStateType.FreeFall then
local Stop_Time = tick()
if (Stop_Time - Track_Time ) > free_fall_Time then
playanimtion()
end
end
end)
You call track:Play(fadeTime, 1, speed) (the third argument tweaks playback speed) or after track:Play immediately do track:AdjustSpeed(speed) to slow down your land animation AnimationTrack, AnimationTrack:AdjustWeight then use humanoid.StateChanged
(fires for freefall > landed HumanoidStateChanged) to save the Y-position on Freefall and compare it on Landed, only running your land anim if startY - endY exceeds your studs threshold, stateType
yea except the default animate script uses its own playAnimation function which doesnt support a speed variable. I could just use normal :Play() but I want to try and keep everything organized and uniform since just switching it for one animation would be weird.
Hm? Well just tweak it to accept an optional speed argument and forward it to the AnimationTrack:Play(fadeTime, weight, speed) call, since Play already supports a speed multiplier as its third parameter it will default to 1 and it lets you slow down only your land anim while keeping every call uniform. If you want to tweak playback you can also call AnimationTrack:AdjustSpeed(speed) afterward, every animation goes through that but you get full control over speed when you need it.
used this and fit it in my script but I notice it spams the logs with multiple checks at a time. Also, after i hit the ground from a valid fall (a time >= free_fall_time) then after the land animation my character just goes into default pose with no animations until I press a movement key.
function onFreeFall()
if (jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
end
pose = "FreeFall"
local free_fall_Time = 1 -- time it takes to play the fall animation
local Track_Time = tick() -- sets the tick
Humanoid.StateChanged:Connect(function(old, new)
if new == Enum.HumanoidStateType.Jumping or new == Enum.HumanoidStateType.Freefall then
print("falling")
Track_Time = tick()
elseif Humanoid:GetState() ~= Enum.HumanoidStateType.Freefall then
print('landed passed')
local Stop_Time = tick()
if (Stop_Time - Track_Time) > free_fall_Time then
playAnimation("land", 0.1, Humanoid, 1)
print('passed time')
pose = "Landed"
end
end
end)
end
yes sorry well i forgot to check if the player actually lands so i just changed it up a bit…
local free_fall_Time = .7 -- time it takes to play the fall animation
local Track_Time = tick() -- sets the tick
local Animation
local function CreateAnimation()
if not Character:FindFirstChild("FallAnim") then
Animation = Instance.new("Animation")
Animation.Name = "FallAnim"
Animation.AnimationId = "rbxassetid://ID"
Animation.Parent = Character
else
Animation = Character:FindFirstChild("FallAnim")
end
local Track: AnimationTrack = Animator:LoadAnimation(Animation)
Track:Play()
end
Humanoid.StateChanged:Connect(function(_, STATE)
if STATE == Enum.HumanoidStateType.Jumping or STATE == Enum.HumanoidStateType.Freefall then
Track_Time = tick()
print("falling or jumpinhg")
elseif Humanoid:GetState() ~= Enum.HumanoidStateType.Freefall and Humanoid:GetState() == Enum.HumanoidStateType.Landed then
local Stop_Time = tick()
print("landed")
if (Stop_Time - Track_Time ) > free_fall_Time then
CreateAnimation()
warn("landed but play animation")
end
end
end)
I appreciate it. I modified it a bit since I didn’t need the CreateAnimation() function as I just added my land anim as a value in the table so it looks like this now
function onFreeFall()
if (jumpAnimTime <= 0) then
playAnimation("fall", fallTransitionTime, Humanoid)
end
pose = "FreeFall"
local free_fall_Time = 1 -- time it takes to play the fall animation
local Track_Time = tick() -- sets the tick
local Animation = animTable["land"][1].anim
local Track: AnimationTrack = Animator:LoadAnimation(Animation)
Humanoid.StateChanged:Connect(function(_, STATE)
if STATE == Enum.HumanoidStateType.Jumping or STATE == Enum.HumanoidStateType.Freefall then
Track_Time = tick()
print("falling or jumping")
elseif Humanoid:GetState() ~= Enum.HumanoidStateType.Freefall and Humanoid:GetState() == Enum.HumanoidStateType.Landed then
local Stop_Time = tick()
print("landed")
if (Stop_Time - Track_Time ) > free_fall_Time then
print("landed worked")
Track:Play()
end
end
end)
end
it plays and continues my idle after now, though there is this weird issue where if the first jump of my character ends up landing and firing the land animation then it looks like and smooth, but if I have jumped prior to a fall that procs the land animation it has a weird cut. Here’s a small video showing this
From what I can tell, this issue is likely due to the script attempting to play the animation multiple times which I see in the output. For some reason, the first time I jump after play testing the log only does one of each message as follows:
However, if I jump more than once (If I have jumped or been airborne more than one time prior to a landing) then it displays this (this is all from one jump):
I’ll tweak it around a bit to see if a debounce or smth can help but if u have an idea that would be great. Thanks regardless.
So I added print(“freefall function run”) to just when the onFreefall() function is run which is the default function that runs when the player’s freefall starts and I notice it is being run multiple times when the player jumps. I’ll try different locations for the script but otherwise I might need a debounce for the freefall function.
Ok pretty sure I fixed it by just removing the onLand() function and just having the statechange:connect be a part of the script on its own to detect the landing.