You can write your topic however you want, but you need to answer these questions:
What do you want to achieve? Keep it simple and clear!
I want to make the avatar land lightly with a light landing animation when the player has been in the air for less than so much time and land heavily with a heavy landing animation when the player has been in the air over a certain amount of time.
What is the issue? Include screenshots / videos if possible!
Tried several different ways, doesn’t behave as expected. Currently when I jump the light landing animation plays everytime and it only lands lightly never heavily.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have tried several ways but cant get any to work… Would anyone be willing to look at the code and tell me what’s wrong with it? Thank you very much in advance.
local char = script.Parent
local hum = char:WaitForChild(("Humanoid"))
local LightLandAnim = Instance.new("Animation")
local ca = tostring(script:WaitForChild("LightLandAnim").AnimationId)
LightLandAnim.AnimationId = ca
local HeavyLandAnim = Instance.new("Animation")
local ca = tostring(script:WaitForChild("HeavyLandAnim").AnimationId)
HeavyLandAnim.AnimationId = ca
local ShouldHeavyLand = false
local StartTime
--code to switch between light land and heavy land animation
hum.StateChanged:Connect(function(OldState,NewState)
if NewState == Enum.HumanoidStateType.Freefall then
StartTime = tick()
delay(.5, function()
if tick() - StartTime >= .5 and hum:GetState() == Enum.HumanoidStateType.Freefall then
ShouldHeavyLand = true
else
ShouldHeavyLand = false
end
end)
elseif hum:GetState() ~= Enum.HumanoidStateType.Freefall then
end
end)
script.Parent.Humanoid.StateChanged:Connect(function(_,state)
if state == Enum.HumanoidStateType.Landed and ShouldHeavyLand == true then
local playAnim = char.Humanoid:LoadAnimation(HeavyLandAnim)
playAnim:Play()
wait(1)
playAnim:Stop()
else
local playAnim = char.Humanoid:LoadAnimation(LightLandAnim)
playAnim:Play()
wait(1)
playAnim:Stop()
ShouldHeavyLand = false
end
end)
at this part you shouldn’t use only else, because it will run every time the state is changed and isn’t landed. You can do
if state == Enum.HumanoidStateType.Landed then
if ShouldHeavyLand == true then
local playAnim = char.Humanoid:LoadAnimation(HeavyLandAnim)
playAnim:Play()
wait(1)
playAnim:Stop()
else
local playAnim = char.Humanoid:LoadAnimation(LightLandAnim)
playAnim:Play()
wait(1)
playAnim:Stop()
ShouldHeavyLand = false
end
end
or just change else to elseif state == Enum.HumanoidStateType.Landed
Oh thank you! of course! That fixed it running everytime the state changed.
I also put the ShouldHeavyLand = false at the end of the first if statement.
But now I have a problem where it always does a heavy landing. I printed ShouldHeavyLand at the end of the freefall check, see:
hum.StateChanged:Connect(function(OldState,NewState)
if NewState == Enum.HumanoidStateType.Freefall then
StartTime = tick()
delay(0.5, function()
if tick() - StartTime >= 0.5 and hum:GetState() == Enum.HumanoidStateType.Freefall then
ShouldHeavyLand = true
else
ShouldHeavyLand = false
end
end)
end
print(ShouldHeavyLand)
end)
And I get this out put when jumping and walking off a ledge:
So i’ve learned from you that the state may be changed multiple times in the air… but I don’t see why it always ends on false (a heavy landing…). I guess if the state is changed multiple times then… it’s not recording the full time from leaving the ground to landing again. But why would the state be changed so many times in the air? Is this just a fact of StateChanged and should i try to switch over to something else (i’ve read about humanoid.floormaterial in passing) or is it a fixable problem with the code? thankk you in advance
local char = script.Parent
local hum = char:WaitForChild(("Humanoid"))
local root = hum.Parent:FindFirstChild("HumanoidRootPart")
local LightLandAnim = Instance.new("Animation")
local ca = tostring(script:WaitForChild("LightLandAnim").AnimationId)
LightLandAnim.AnimationId = ca
local HeavyLandAnim = Instance.new("Animation")
local ca = tostring(script:WaitForChild("HeavyLandAnim").AnimationId)
HeavyLandAnim.AnimationId = ca
-- when landing, check the downward velocity if it is over 100 play different animation (SO IT IS POSSIBLE TO GET VELOCITY)
script.Parent.Humanoid.StateChanged:Connect(function(_,state)
if state == Enum.HumanoidStateType.Landed then
-- if dashing, then dont play landing animation
if game.Players.LocalPlayer.Character:FindFirstChild("Dashing") then
return end
local fallVelocity = -root.Velocity.Y
if fallVelocity > 100 then
print(fallVelocity)
local playAnim = char.Humanoid:LoadAnimation(HeavyLandAnim)
playAnim:Play()
wait(1)
playAnim:Stop()
else
local playAnim = char.Humanoid:LoadAnimation(LightLandAnim)
playAnim:Play()
wait(1)
playAnim:Stop()
end
end
end)
I figured there must be a way to check velocity but couldnt find it at first on the forum. This is definitely simpler.