When listening to a player’s Humanoid on a client who is the player, StateChanged works perfectly fine. The following are printed consistently every time when jumping:
-- Jump 1
Enum.HumanoidStateType.Jumping
Enum.HumanoidStateType.Freefall
Enum.HumanoidStateType.Landed
Enum.HumanoidStateType.Running
-- Jump 2
Enum.HumanoidStateType.Jumping
Enum.HumanoidStateType.Freefall
Enum.HumanoidStateType.Landed
Enum.HumanoidStateType.Running
-- Jump 3
Enum.HumanoidStateType.Jumping
Enum.HumanoidStateType.Freefall
Enum.HumanoidStateType.Landed
Enum.HumanoidStateType.Running
Meanwhile, when listening to a player’s Humanoid on clients who are not the player, StateChanged fires inconsistently. Sometimes Jumping
doesn’t fire, sometimes Landed
doesn’t fire, sometimes they both don’t fire, sometimes they all fire, etc:
-- Jump 1
Enum.HumanoidStateType.Jumping
Enum.HumanoidStateType.Landed
-- Jump 2
Enum.HumanoidStateType.Jumping
Enum.HumanoidStateType.Freefall
Enum.HumanoidStateType.Landed
Enum.HumanoidStateType.Running
-- Jump 3
Enum.HumanoidStateType.Jumping
Enum.HumanoidStateType.Freefall
Enum.HumanoidStateType.Running
(localPlayer ~= player
on left, localPlayer == player
on right)
targetPlayerHumanoid.StateChanged:Connect(function(old, new)
print("old, new = ", old, new)
if new == Enum.HumanoidStateType.Jumping then
print("Target jumped!")
elseif old == Enum.HumanoidStateType.Landed or (old == Enum.HumanoidStateType.Freefall and new ~= Enum.HumanoidStateType.Landed) then
print("Target jump ended!")
end
end)
This is incredibly frustrating and makes listening to StateChanged
(e.g. to detect jumping) on other clients completely impossible to do reliably.
The developer API also specifically states to use StateChanged to detect jump landings, and as far as I’m aware this is impossible to do reliably without additional complexities such as raycasting.
This bug report is also similar to an unresolved one from three years ago: Humanoid.StateChanged for jumping and Humanoid.Jumping do not fire consistently