Current Issue, with the way I am detecting if the player just lands is not working as expected. Code
if humanoid.FloorMaterial ~= Enum.Material.Air and not Player_In_Air then
Just_Landed = true
task.delay(LAND_FREE_TIME, function()
if Player_In_Air then
Just_Landed = false
else
Just_Landed = false
end
end)
end
The expected result I want is if the player lands then Just_Landed = true else its false, but if the player jumps again during the timeframe Just_Landed = false.
Anybody have any ideas or better methods this?
FullCode
function renderteppedFunction(ResponseDelay: number)
if humanoid.FloorMaterial == Enum.Material.Air then
Player_In_Air = true
else
Player_In_Air = false
end
Current_Move_Direction = Vector3.new(humanoid.MoveDirection.X, humanoid.MoveDirection.Y, humanoid.MoveDirection.Z)
if humanoid.FloorMaterial ~= Enum.Material.Air and not Player_In_Air then
Just_Landed = true
task.delay(LAND_FREE_TIME, function()
if Player_In_Air then
Just_Landed = false
else
Just_Landed = false
end
end)
end
print(Just_Landed)
task.wait(ResponseDelay)
end
Issue with this Is I am going to be doing custom state management later.
BUT the main issue with this is I have tried doing Humanoid:Getstate() of landed, and added a os.clock to it but that did not work at all, even though my code was 100% correct after I talked to 3 other people about it.
Humanoid:GetState() is not a good thing to use in my opinion after what I just dealt with it.
You are setting Just_Landed to true every frame that you’re on the ground, and then setting it to false after a delay? As long as you stay on the ground, I presume that would change your value back and forth.
It shouldent change back and forth, in which it Doesent. But right now I am thinking of something to fix it, which i think I may have found. I just need to think harder
function renderteppedFunction(ResponseDelay: number)
if humanoid.FloorMaterial == Enum.Material.Air then
Player_In_Air = true
else
Player_In_Air = false
end
Current_Move_Direction = Vector3.new(humanoid.MoveDirection.X, humanoid.MoveDirection.Y, humanoid.MoveDirection.Z)
if humanoid.FloorMaterial ~= Enum.Material.Air and not Player_In_Air then
Just_Landed = true
task.delay(LAND_FREE_TIME, function()
if Player_In_Air then
Just_Landed = false
else
Just_Landed = false
end
end)
end
if Player_In_Air then
Just_Landed = false
end
print(Just_Landed)
task.wait(ResponseDelay)
end
I added
if Player_In_Air then
Just_Landed = false
end
because that will not be checked nonstop in the task.delay
humanoid state is pretty unreliable sometimes, so I found the most reliable way is to use a combination of both humanoid state and a raycast downwards (or towards where the player is heading) to check if it hit the ground.
Below is some basic pseudocode to get you started. Commented some parts but if there’s something you don’t understand lmk
local raycastParams = ...
local previousPosition = character.PrimaryPart.Position
local currentPosition = character.PrimaryPart.Position
local raycastDistance = 3
local direction
local connection = nil
connection = RunService.Heartbeat:Connect(function()
currentPosition = character.PrimaryPart.Position
direction = (currentPosition - previousPosition).Unit --direction here
if currentPosition ~= previousPosition then
--raycast towards the direction the player is being thrown in
local raycastResult = workspace:Raycast(character.PrimaryPart.Position, direction * raycastDistance, raycastParams)
if raycastResult then
--create a new part and set its cframe for visual effect to see where it landed
local groundPart = Instance.new("Part")
groundPart.CFrame = CFrame.lookAt(raycastResult.Position, raycastResult.Position + raycastResult.Normal)
groundPart.Parent = workspace
--disconnect the connection
connection:Disconnect()
connection = nil
end
end
--set the new position here
previousPosition = currentPosition
end)
I’d personally skip the task.delay() mechanism, since it really only adds confusion, and just do something more like this:
local inAir = false
local justLanded = false
local lastLandingTime = 0
local LAND_FREE_TIME = 0.5
function OnRenderstep( dt )
local now = tick()
local prevInAir = inAir
inAir = humanoid.FloorMaterial == Enum.Material.Air
if prevInAir and (not inAir) then
justLanded = true
lastLandingTime = now
end
if inAir or now > lastLandingTime + LAND_FREE_TIME then
justLanded = false
end
end
There are a few different functions built into Roblox Luau that get you a time: time(), os.time(), and tick(). They are all in seconds, the difference is that time() is seconds since the server/client started up, where as tick() and os.time() are seconds since the Unix Epoch of 1/1/1970. One of them adjusts for time zone as well. When all you care about is elapsed differences, it’s pretty common to use either tick() or time(), and just be consistent with it.
Since everything is happening on Renderstepped, you could also just accumulate the dt value yourself in a local variable. The end result would be the same.