-- // 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