I’m trying to implement a fall damage system to my game. I would gladly use HumanoidStates to detect when the player hits the ground but sadly my game’s ragdoll system overrides a player’s HumanoidState with the Physics state every time they reach a certain velocity. I decided to use a method that casts a ray downward from the player’s HumanoidRootPart every frame and checks if the ray length is shorter than or equal to the player’s height. This works most of the time but starts failing when the player hits the ground with a very fast velocity. How can I fix this? Here is a simplified version of the script:
game:GetService("RunService").Heartbeat:Connect(function()
if(canFall) then
local humHeight = (0.5 * humRootPart.Size.Y) + hum.HipHeight + 1
local yVelocity = humRootPart.Velocity.y
if(yVelocity > 0 or math.floor(yVelocity) == 0) then
return
end
yVelocity = math.abs(yVelocity)
local rayOrigin = humRootPart.Position
local rayDirection = Vector3.new(0, -500, 0)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {char,debugFolder}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if (raycastResult) then
local hitPos = raycastResult.Position
local distance = math.abs(humRootPart.Position.y - hitPos.y)
if(yVelocity >= minVelocity.Value and distance <= humHeight) then
canFall = false
--Deal damage based on yVelocity
wait(fallCooldownTime.Value)
canFall = true
end
end
end
end)