Why CloneTrooper1019's Perfected Ragdoll System breaks reseting?

Hello, i use a modified version of CloneTrooper1019’s Perfected Ragdoll System to create a ragdoll, however, i’ve noticed that the script breaks reseting, i’ve been looking into the script for a long time, yet i don’t find anything that may break the character, can anyone help me find the problem?

Script

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- @CloneTrooper1019, 2015
-- Perfected Ragdoll System
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-- To use this, just place it inside of the ServerScriptService
-- If you encounter any serious problems, feel free to tweet me @CloneT1019, and I'll investigate.
-- Enjoy!

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
																																																																															--[[
~ IMPORTANT TECHNICAL NOTES ~

	*		To make sure the joints function correctly, make sure you have the
			PGSPhysicsSolverEnabled property checked. If you don't, you may
			occasionally encounter exploding spasming ragdolls.
			
	*		There is a LocalScript inside of this script called LocalRagdoll.
			DO NOT DELETE THIS. It is crucial to make sure this script is compatable online
			
		*		This script will automatically parent the LocalRagdoll script into the StarterCharacterScripts
				service. If you'd like to, you can feel free to just drag it into StarterPlayer/StarterCharacterScripts
				yourself.

																																																						--]]

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Process LocalRagdoll
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

local function processLocalRagdoll(localRagdoll)
	if localRagdoll.Name == "LocalRagdoll" and localRagdoll:IsA("LocalScript") then
		local starterPlayer = game:GetService("StarterPlayer")
		local starterCharacterScripts = starterPlayer:FindFirstChild("StarterCharacterScripts")
		if not starterCharacterScripts then
			starterCharacterScripts = Instance.new("StarterCharacterScripts",starterPlayer)
		end
		if not starterCharacterScripts:FindFirstChild("LocalRagdoll") then
			localRagdoll.Parent = starterCharacterScripts
			localRagdoll.Disabled = false
			
			for _,v in pairs(game.Players:GetPlayers()) do
				local char = v.Character
				if char then
					if not char:FindFirstChild("LocalRagdoll") then
						localRagdoll:clone().Parent = char
					end
				end
			end
		end
	end
end

if script:FindFirstChild("LocalRagdoll") then
	processLocalRagdoll(script.LocalRagdoll)
else
	script.ChildAdded:connect(processLocalRagdoll)
end

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Main Code
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

local debris = game:GetService("Debris")
local addItem = debris.AddItem

if not workspace:PGSIsEnabled() then
	warn(script:GetFullName(),"-","WARNING: Workspace.PGSPhysicsSolverEnabled is false. This may cause problems.")
end

local function remakeJoint(type,data)
	if data.Part0 and data.Part1 then
		local new = Instance.new(type)
		for k,v in pairs(data) do
			new[k] = v
		end
		new.Parent = new.Part0
	end
end

function registerCharacter(char)
	local Deletion = {}
	local player = game.Players:GetPlayerFromCharacter(char)
	local humanoid = char:WaitForChild("Humanoid")
	local rootPart = char:WaitForChild("HumanoidRootPart")
	local torso = char:WaitForChild("Torso")
	local head = char:WaitForChild("Head")
	local motorMemory = {}
	local weldMemory = {}
	local isDead = false
	local registeredJoints = {}
	local counter = -1
	local function registerJoints(object)
		if object:IsA("BasePart") then
			local function checkChild(v)
				if not isDead then
					if v:IsA("Motor6D") or v:IsA("Weld") then
						local tableToUse = motorMemory
						counter= counter+1
						Deletion[counter] = v
						if v:IsA("Weld") or v.Name == "Neck" then
							tableToUse = weldMemory
						end
						if tableToUse then
							local register = {}
							register.Name = v.Name
							register.Part0 = v.Part0
							register.Part1 = v.Part1
							register.C0 = v.C0 * CFrame.new(v.C0.p * 0.01) -- Offset it just ever-so slightly so we don't cause overconstraining in the new solver.
							register.C1 = v.C1
							table.insert(tableToUse,register)
							table.insert(registeredJoints,v)
						end
					end
				end
			end
			for _,v in pairs(object:GetChildren()) do
				checkChild(v)
			end
			object.ChildAdded:connect(checkChild)
		end
	end
		
	for i,v in pairs(char:GetChildren()) do
		registerJoints(v)
	end
		
	local jointCon = char.ChildAdded:connect(registerJoints)

	local pingClient = Instance.new("RemoteFunction")
	pingClient.Name = "PingClient"
	pingClient.Parent = humanoid
		
	local function onDied()
		isDead = true
		rootPart:Destroy()
		for i = #Deletion,1,-1 do
			if Deletion[i].Name ~= "Accessory Weld" then
				Deletion[i]:Destroy()
			end
		end
		
		for _,motor in pairs(motorMemory) do
			remakeJoint("Rotate",motor)
		end
			
		for _,weld in pairs(weldMemory) do
			local part = weld.Part1
			local canRemake = true
			if part then
				if part.Name == "Handle" and part.Parent and part.Parent:IsA("Accoutrement") then
					if not part.Parent:IsDescendantOf(char) then
						canRemake = false
					end
				end
			end
			if canRemake then
				remakeJoint("Weld",weld)
			end
		end
		
		if torso:CanSetNetworkOwnership() then
			torso:SetNetworkOwner(player)
		end
		pingClient:InvokeClient(player) -- Yield until the changes from the server replicate to the client.
		
		humanoid.AutoRotate = false
		humanoid:UnequipTools()
		humanoid:SetStateEnabled("Jumping",false)
		humanoid:SetStateEnabled("GettingUp",false)
		humanoid:SetStateEnabled("Dead",true)
		humanoid:ChangeState("Dead")
		
		local function onChildAdded(child)
			if child:IsA("Tool") then
				addItem(debris,child,0)
			end
		end
		
		char.ChildAdded:connect(onChildAdded)
		
		local bar = Instance.new("Part")
		bar.TopSurface = 0
		bar.BottomSurface = 0
		bar.FormFactor = "Custom"
		bar.Size = Vector3.new(1,1.4,1)
		bar.Transparency = 1
		bar.Parent = char
		
		local w = Instance.new("Weld",torso)
		w.Part0 = torso
		w.Part1 = bar
		w.C0 = CFrame.new(0,.5,0)
		
		local velocity = torso.Velocity
		local motion = velocity.magnitude

		if motion < 10 then
			if motion < 1e-6 then
				torso.Velocity = Vector3.new(0,10,0)
			else
				torso.Velocity = velocity * (10/motion)
			end
		end
		
		-- Garbage collection
		jointCon:disconnect()
		jointCon = nil
		motorMemory = nil
		weldMemory = nil
		registeredJoints = nil
		Deletion = nil
	end
	
	local function onHealthChanged(health)
		if health <= 0 and not isDead then
			onDied()
		end
	end
	
	humanoid:SetStateEnabled("Dead",false)
	humanoid.HealthChanged:connect(onHealthChanged)
end

function onPlayerEntered(player)
	player.CharacterAdded:connect(registerCharacter)
end

game.Players.PlayerAdded:connect(onPlayerEntered)
print("Ragdolls: Successfully loaded!")

LocalScript (Parented to script)

local char = script.Parent
local humanoid = char:WaitForChild("Humanoid")
humanoid:SetStateEnabled("Dead",false)

local pingClient = humanoid:WaitForChild("PingClient")
local lastReceive = tick()
local isDead = false
local util = LoadLibrary("RbxUtility")
local receive = util.CreateSignal()

function pingClient:OnClientInvoke()
	receive:fire()
	lastReceive = tick()
	return true
end

local function onHealthChanged(health)
	if health <= 0 and not isDead then
		isDead = true
		
		local now = tick()
		if (now - lastReceive) > 1 then
			receive:wait()
		end
		
		humanoid:SetStateEnabled("Dead",true)
		humanoid:ChangeState("Dead")
	end
end

humanoid.HealthChanged:connect(onHealthChanged)

@CloneTrooper1019 is the best person to ask about this, obviously.

3 Likes

I’ve not looked at any of the code, but I do know that if the humanoid is renamed then resetting won’t work.

the humanoid is not renamed, i’ve already checked for that.

thought it would be a good idea to ask in the scripting support before contacting CloneTrooper1019

The answer is in the top: the code is from 2015. Look at newer ragdoll scripts and compare them, or make your own.

As i said, i modified the script to make it comply with more modern roblox standards, things like checking for accessories instead of hats.

There’s a reason that i’m “not making my own” , i don’t have any experience with welding/joints/“Balls in a socket”

Probably because I disable the Humanoid’s death state. I had made this when Roblox was super picky about the humanoids joint breakage while the health was zero. You may want to modify it to utilize the new BreakJointsOnDeath property.

Also whoever flagged @unix_system in this post did so inappropriately.

19 Likes

Oh, i guess that solves everything. I will be sure to reply if it doesn’t work.

Edit: Removed all calls to change the dead state, and changed how the script detects death (Now uses Humanoid.Died), reseting now works like it should.

1 Like