I’ve made a ragdoll system for my game, and it works as expected during regular gameplay, however when it came to making a ragdoll death, thats when I started running into some issues.
Keep in mind that the game I want this to run in has custom character designs.
The first video is what currently happens when I try to reset:
The second is what happens with the same system with essentially a blank baseplate: (just a testing place)
The third is a comparison of the server vs the client’s perspective on what happens in the main game when I try to reset:
Here is the system that is used in both places:
– MODULE (CONTROLLED BY SERVER, PLACED IN REPLICATEDSTORAGE) –
local module = {}
function module.Ragdoll(char, stunTime) -- the function that is called by the server
stunTime = stunTime or 0
pcall(function()
if char.Ragdolled.Value then return end
char.Ragdolled.Value = true
for i, joint in pairs(char:GetDescendants()) do
if
joint:IsA('Motor6D')
and joint.Name ~= 'RightArmPart'
and joint.Name ~= 'LeftArmPart'
and joint.Name ~= 'TorsoPart'
and joint.Name ~= 'RightLegPart'
and joint.Name ~= 'LeftLegPart'
then
local socket = Instance.new('BallSocketConstraint', joint.Parent)
local att0 = Instance.new('Attachment', joint.Part0)
local att1 = Instance.new('Attachment', joint.Part1)
att0.CFrame = joint.C0
att1.CFrame = joint.C1
socket.Attachment0 = att0
socket.Attachment1 = att1
socket.TwistLimitsEnabled = true
socket.LimitsEnabled = true
joint.Enabled = false
end
end
if stunTime ~= 0 then
task.delay(stunTime, function()
module.Unragdoll(char)
end)
end
end)
end
function module.Unragdoll(char) -- ignore this
pcall(function()
char.Ragdolled.Value = false
for i, joint in pairs(char:GetDescendants()) do
if joint:IsA('Motor6D') then
joint.Enabled = true
elseif joint:IsA('BallSocketConstraint') then
joint.Enabled = false
end
end
end)
end
return module
– SERVER (PLACED IN SERVERSCRIPTSERVICE) –
local RS = game:GetService('ReplicatedStorage')
local ragollmod = require(RS:WaitForChild('RagdollHandler'))
game.Players.PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(char)
char.Humanoid.BreakJointsOnDeath = false
local bool = Instance.new('BoolValue')
bool.Name = 'Ragdolled'
bool.Value = false
bool.Parent = char
task.delay(3, function()
ragollmod.Ragdoll(char, 2)
end)
char.Humanoid.Died:Connect(function()
ragollmod.Ragdoll(char)
end)
end)
end)
– CLIENT (PLACED IN STARTERCHARACTERSCRIPTS/CUSTOM CHARACTER MODEL) –
local Players = game:GetService('Players')
local RuS = game:GetService('RunService')
local player = Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char:WaitForChild('Humanoid')
local ragdolled = char:WaitForChild('Ragdolled')
local function change_state()
if hum:GetState() == Enum.HumanoidStateType.Dead then
--
else
if ragdolled.Value then
RuS:BindToRenderStep('RagdollStun', Enum.RenderPriority.Character.Value + 14, function()
hum:ChangeState(Enum.HumanoidStateType.Physics)
end)
else
RuS:UnbindFromRenderStep('RagdollStun')
hum:ChangeState(Enum.HumanoidStateType.GettingUp)
end
end
end
ragdolled:GetPropertyChangedSignal('Value'):Connect(change_state)
If anyone knows why this is the case, let me know!