Detect when player lands, but not after jumping

Hey everyone, I’m trying to detect when the player lands, but all the info that I found is about when the landing happens after a jump, which is not my case, as I’m moving the player with scripts, with this code more specifically:

	game:GetService("TweenService"):Create(humanoidRootPart, TweenInfo.new(TweenTime, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {
		CFrame = humanoidRootPart.CFrame * CFrame.new(0, TweenHeight, -4)
		
	}):Play()

So, the traditional way of detecting if player landed does not work in this case. This is what I have tried so far, but as you may guess, it didn’t worked.

	local debounce = false

	local function onTouched(hit)
		if hit:IsA("BasePart") and not debounce then
			debounce = true
			wait(0.5) event
			print("PLS LAND")
			debounce = false
		end
	end

This will NOT work, because player is not jumping:

Humanoid.StateChanged:Connect(function(old,new)
	if new == Enum.HumanoidStateType.Landed then
		print("stuff")
	end	
end)

Thank you in advance!

you can use Humanoid.StateChanged to get the current state of the humanoid, whether it is jumping, running, or landed.

1 Like

I know. I could easily do that:

Humanoid.StateChanged:Connect(function(old,new)
	if new == Enum.HumanoidStateType.Landed then
		print("stuff")
	end	
end)

But the thing is, it only works whenever the player jumps, which is not the case on the main script

2 Likes

An easier and more reliable way to detect when the character has landed is to watch the humanoid for when its state becomes Enum.HumanoidStateType.Landed. Using this in conjunction with tracking the jump state you can get the behavior you want.

local isJumping = false

humanoid.StateChanged:Connect(function(oldState, newState)
	if newState == Enum.HumanoidStateType.Jumping then
		isJumping = true
	elseif newState == Enum.HumanoidStateType.Landed then
		if not isJumping then
			print"I just landed without jumping!"
		end
		
		isJumping = false
	end
end)
3 Likes

Not sure what all you’re doing … this may work.

---local script
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local db=true
humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
	if db and humanoid.FloorMaterial == Enum.Material.Air then db=false
	elseif not db and humanoid.FloorMaterial ~= Enum.Material.Air then db=true
		print("landed")
	end
end)

Using PropertyChangedSignal with an elseif and a bool (flag):

Testing to see if player is in the air, setting a bool if so to false.
If bool is set (false) testing for when not in the air … resetting bool (true)

Also a server script is a bit sketchy with this. May have to use a remote from a local script, if you really want to have the reaction in a server script.

unfortunely it only works if the player holds space and w at the same time… no idea why.

the same happening with this one

If the Humanoid functions fail, the next best thing to utilize is the position of the character to determine what speed would be considered falling. By making a loop to log the falling speed per tenth of a second, you can calculate the difference between the numbers and thus get the distance travelled in the timeframe.

Here’s an example of such script;

local player = game.Players.LocalPlayer
local character = player.Character
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

local prevPos = humanoidRootPart.CFrame
local WAIT_TIME = 0.1
local maxFall = 6
local isFalling = false

while true do
	
	prevPos = humanoidRootPart.Position.Y
	task.wait(WAIT_TIME)
	local currentPos = humanoidRootPart.Position.Y
	
	local posDiff = math.abs(math.round(prevPos - currentPos))
	
	if posDiff >= maxFall then
		
		if not isFalling then
			isFalling = true
			print("Fall started.") --//Debug
		end
		
		print("Falling faster than " .. maxFall .. " studs;", posDiff) --//debugging purposes
		
	else
		
		if isFalling then
			isFalling = false
			print("Fall ended.") --//Debug
		end
		
	end
	
end

This code will know when the player started falling and when they land. I put the maxFall at 6 since the player will not be able to jump faster than a 6 stud difference, so it will not confuse the script.

3 Likes

I don’t see how, works fine for me and has nothing to do with jumping or the spacebar.
Simply a in air now to a not in air test. I said this code on a server script is a bit sketchy. I should have used the word spotty. This has to be done on a local script to be accurate. Try that in StarterGui in a local script by itself to isolate testing. “Not sure what all you’re doing”

Just copied the script started a new program and tried the script in a local script from StarterGui and then from StarterPlayer.StarterPlayerScripts and both worked fine …

1 Like

You could use :GetPropertyChangedSignal() to detect when the player’s in the air, i’ll give an example below.

Humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
	if Humanoid.FloorMaterial == Enum.Material.Air then
		Humanoid:GetPropertyChangedSignal("FloorMaterial"):Wait()
		
		if Humanoid.FloorMaterial ~= Enum.Material.Air then
			print("Landed")
		end
	end
end)
1 Like

You can track when the player jumps using a boolean variable.

You can make it true when a player jumps and false when they land.

But you won’t set it if they don’t jump.

local jumpVal = false

Humanoid.StateChanged:Connect(function(old,new)
	if new == Enum.HumanoidStateType.Jumped then
        jumpVal = true
	end	
end)

Humanoid.StateChanged:Connect(function(old,new)
	if new == Enum.HumanoidStateType.Landed then
        jumpVal = false
	end	
end)
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.