How do I detect if the player collided with the ground if they are ragdolled?

-- // PLAYER CONSTANTS //
local char = script.Parent
local hrp = char:WaitForChild("HumanoidRootPart")
local humanoid = char:FindFirstChild("Humanoid")
---------------------------------------------------

-- // SERVICES //
local RepStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")
---------------------------------------------------

-- // REMOTE-EVENT FOR RAGDOLL TOGGLE //
local ragEvent = RepStorage:WaitForChild("Ragdoll")
---------------------------------------------------

-- /// CONFIG /// --

-- // FALL TIME
local FALL_TIME_THRESHOLD = script:GetAttribute("FALL_TIME_THRESHOLD") -- Time in seconds before ragdolling

-- // FALL DAMAGE
local SECONDS_THRESHOLD = 5
local DAMAGE_PER_SECOND = 10

-- / 'While' loop speed
local TICK_TIME = script:GetAttribute("TICK_TIME")
--------------------------

-- // Variables to track fall time
local fallingStartTime = nil
local isRagdolled = false

local function applyFallDamage(fallingDuration)
    --[[ 
    applyFallDamage(fallingDuration)
    +++
    Applies fall damage based on how long the player has been falling.
    ]]
	if fallingDuration >= SECONDS_THRESHOLD then
		local damage = (fallingDuration - SECONDS_THRESHOLD) * DAMAGE_PER_SECOND
		humanoid:TakeDamage(damage)
		print("Player took fall damage: " .. damage)
	else
		print("Fall was too short to take damage.")
	end
end

local function ragdoll()
    --[[ 
    ragdoll()
    +++
    Ragdolls the player by disabling the Motor6D constraints and adding ball sockets instead.
    ]]
	isRagdolled = true
	for _, joint in pairs(char:GetDescendants()) do
		if joint:IsA("Motor6D") then
			local socket = Instance.new("BallSocketConstraint")
			local a1 = Instance.new("Attachment")
			local a2 = Instance.new("Attachment")
			a1.Parent = joint.Part0
			a2.Parent = joint.Part1
			a1.Name = "RagdollAttachment"
			a2.Name = "RagdollAttachment"
			socket.Parent = joint.Parent
			socket.Attachment0 = a1
			socket.Attachment1 = a2
			a1.CFrame = joint.C0
			a2.CFrame = joint.C1
			socket.LimitsEnabled = true
			socket.TwistLimitsEnabled = true
			joint.Enabled = false
		end
	end
	ragEvent:FireClient(Players:GetPlayerFromCharacter(char), true)
	print("Ragdolled!")
end

local function unragdoll()
    --[[ 
    unragdoll()
    +++
    Unragdolls the player by enabling the Motor6D constraints and deleting ball sockets.
    ]]
	isRagdolled = false
	for _, socket in pairs(char:GetDescendants()) do
		if socket:IsA("BallSocketConstraint") then
			socket:Destroy()
		end
	end
	for _, attachment in pairs(char:GetDescendants()) do
		if attachment:IsA("Attachment") and attachment.Name == "RagdollAttachment" then
			attachment:Destroy()
		end
	end
	for _, joint in pairs(char:GetDescendants()) do
		if joint:IsA("Motor6D") then
			joint.Enabled = true
		end
	end
	ragEvent:FireClient(Players:GetPlayerFromCharacter(char), false)
	print("Unragdolled!")
end

local function checkDistanceToGround()
    --[[ 
    checkDistanceToGround() 
    +++ 
    Checks the distance from the HRP (Humanoid Root Part) to the ground. 
    If the player is in freefall and has been falling for a certain time, the player will ragdoll.
    ]]

	-- // Check if the player is in freefall
	if humanoid:GetState() == Enum.HumanoidStateType.Freefall then
		if not fallingStartTime then
			fallingStartTime = tick() -- Start tracking fall time
		else
			local fallingDuration = tick() - fallingStartTime
			if fallingDuration >= FALL_TIME_THRESHOLD then
				ragdoll()
				fallingStartTime = nil -- Reset fall time after ragdolling
			end
		end
	else
		fallingStartTime = nil
	end
end

-- Main loop to check for fall conditions
while true do
	print(hrp.Velocity.Y)
	checkDistanceToGround()
	task.wait(TICK_TIME)
end

I’ve written a script that:

  • Checks if the player has fallen for a while
  • If they have fallen for more than allowed, they ragdoll.

Problem: I have no idea how to detect if they collide with the ground. The rig is R6.
States are as follows:
Unragdolled:
Enum.HumanoidStateType.GettingUp
Ragdolled:
Enum.HumanoidStateType.Physics

humanoid.StateChanged:Connect(function(oldState, newState)
	if  newState == Enum.HumanoidStateType.Landed  then
		-- event
	end
end)

This did not work. (key limit…)

You can detect if the current velocity-before velocity is lower than 10, this would mean you made an impact.

let’s say you’re falling 70 studs.
you stop, having 0 studs now.
70-0 = 70

70 is higher than 10, so it’s an impact.

you can detect this in a stepped event or if you want a more reliable service you can do it on the client using renderstpped and use remotevents to ragdoll and damage if you want:

this is not a working script, but it’s a base for what I mean.

local beforevelo = 0 
local root = Character:WaitForChild("HumanoidRootPart")

runservice.rebderstepped()
local calulation = beforevelo - root.Velo.Magnitude

if calulation>=10
remotevent:FireServer(magnitude) -- on the server, you can calculate the damage based on the magnitude, and ragdoll the charcater
end

beforevelo = root.Velo.Magnitude
end)
1 Like

You could try raycasting or checking their floor material

Ooh sorry for the late reply, this seemed to work, thank you!

1 Like

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