Ragdoll Issue Limbs clipping

Hello, so I have a ragdoll system, when I ragdoll the player can move and the player acts all fishy, literally, here is an image:

image

I don’t want to use platformstand because then limbs fall through the map making it all weird, and if I turn on collisions the limbs get trapped through the floor:

image

I tried different things such as Setting the humanoid state to Physics, Ragdoll, and FallingDown as well as disabling the enabled state of GettingUp, Jumping, and Seated yet none of it ragdolls the player in a way that character cannot move by user input, and making the humanoid lay on the floor due to ragdoll.

CODE:

function ToggleRagdollPlayer(Player: Player, Enable: boolean)
	if not Player then return end
	if not Player.Character then return end
	
	local Humanoid: Humanoid = Player.Character:WaitForChild("Humanoid")
	
	local Motor6Ds = {
		["Left Hip"] = "Left Leg",
		["Right Hip"] = "Right Leg",
		["Neck"] = "Head",
		["Right Shoulder"] = "Right Arm",
		["Left Shoulder"] = "Left Arm"
	} 
	
	-- Loop Through each limb.
	for _, Part in pairs(Player.Character:GetChildren()) do
		if not Part:IsA("BasePart") then continue end
		
		local PartMotorName = FindIndexByValue(Motor6Ds, Part.Name)
		if PartMotorName == nil then continue end
		
		
		local Motor6D: Motor6D = Player.Character:WaitForChild("Torso"):FindFirstChild(PartMotorName)
		local Attachment0: Attachment
		local Attachment1: Attachment
		local BallSocket: BallSocketConstraint
		
		local PreviousPartAttachment = Part:FindFirstChild(Part.Name)
		if PreviousPartAttachment ~= nil and PreviousPartAttachment:IsA("Attachment") then
			Attachment1 = PreviousPartAttachment
		else
			Attachment1 = Instance.new("Attachment")
			Attachment1.Name = Part.Name
			Attachment1.Parent = Part
			Attachment1.CFrame = Motor6D.C1
		end
		
		local PreviousTorsoAttachment = Player.Character:WaitForChild("Torso"):FindFirstChild(Part.Name)
		if PreviousTorsoAttachment ~= nil and PreviousTorsoAttachment:IsA("Attachment") then
			Attachment0 = PreviousTorsoAttachment
		else
			Attachment0 = Instance.new("Attachment")
			Attachment0.Name = Part.Name
			Attachment0.Parent = Player.Character:WaitForChild("Torso")
			Attachment0.CFrame = Motor6D.C0
		end
		
		local PreviousBallSocket = Player.Character:WaitForChild("Torso"):FindFirstChild(Part.Name.." Ragdoll")
		if PreviousBallSocket ~= nil and PreviousBallSocket:IsA("BallSocketConstraint") then
			BallSocket = PreviousBallSocket
		else
			BallSocket = Instance.new("BallSocketConstraint")
			BallSocket.Name = Part.Name.." Ragdoll"
			BallSocket.Parent = Player.Character:WaitForChild("Torso")
			BallSocket.Attachment0 = Attachment0
			BallSocket.Attachment1 = Attachment1
			BallSocket.LimitsEnabled = true
			BallSocket.Enabled = false
			BallSocket.TwistLimitsEnabled = true
		end
		
		if Enable == true then
			BallSocket.Enabled = true
			Motor6D.Enabled = false
		else
			Motor6D.Enabled = true
			BallSocket.Enabled = false
		end
	end
	
	if Enable == true then
		Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, false)
		Humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, false)
		Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
		if Humanoid.Health > 0 then
			Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
		end
		Humanoid.WalkSpeed = 0
		--Humanoid.PlatformStand = true
	else
		Humanoid:SetStateEnabled(Enum.HumanoidStateType.GettingUp, true)
		Humanoid:SetStateEnabled(Enum.HumanoidStateType.Seated, true)
		Humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
		if Humanoid.Health > 0 then
			Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
		end
		Humanoid.PlatformStand = false
		Humanoid.WalkSpeed = 16
	end
	
end
4 Likes

ContextActionService to the rescue.

You can bind and unbind actions using CAS, and it just so happens that player movements are mapped with it.

CAS also has a priority system, which means if you make an action on the same bind that is a higher priority than the other one, then the higher priority bind will take precedence.

The solution is pretty easy, just sink the players inputs when you are in ragdoll, and then remove the sink when you are done.

local ContextActionService = game:GetService("ContextActionService")

if Enable then
	ContextActionService:BindActionAtPriority("MovementSink", function() return Enum.ContextActionResult.Sink end, false, 3000, 
		Enum.PlayerActions.CharacterLeft, 
		Enum.PlayerActions.CharacterRight,
		Enum.PlayerActions.CharacterForward, 
		Enum.PlayerActions.CharacterBackward,
		Enum.PlayerActions.CharacterJump
	)
else
	ContextActionService:UnbindAction("MovementSink")
end
1 Like

This will work on server side right?, because my script is based on server only to protect it from exploiters.

1 Like

Unfortunately not, but an easier way that I probably should have thought of to start with is just setting the humanoids walkspeed and jumppower to 0.

1 Like

I guess this tackles one of the problems, but still have the freaking limbs clipping issue, next update we need is a humanoid state update because why not.

Why don’t you just set the CanCollide property for all the limbs to true?

humanoid behavior is the definition of a fortnite kid (EXTREME CANCER), if you try to change cancollide it will cry and set it back to false

I… don’t notice that when doing it, not sure if its some part of changing the state of the humanoid but it should just work.

I try turning on platform stand, but the catch is that the torso is the only thing thats collideable, and I run a loop through each part of the character and set cancollide to true, yet it doesn’t fully work. Trying to change states I found out that ITS always running, I wish I could do something like a dead state, where limbs don’t fall through the map and player can’t move.

To protect the game from exploiters, you’ll need to either do some checks on the server or change the network ownership of the character to the server.

Also, humanoid states need to be set by the network owner of the character’s BaseParts. if the client is the network owner of their character’s parts (which is the case by default), you need to set humanoid states on the client. In my ragdoll system that I’m working on, I use the physics humanoid state.

1 Like

Is this a function that occurs when the Player health reaches 0

Changing the ownership temporarly until player ragdoll gets toggled seems reasonable, also if I change the humanoid state would it replicate?

is there any errors involved in the Script?

No, but I use it when player dies and works fine, but when player is alive thats another tale.

no, not at all, just not a desirable behavior happening.

You might need to break the BallSocket through the Ragdoll

Maybe looping the function could cause abrupt disability

Based on printing the state in the command bar on both client and server after setting it on the client, it seems like it sometimes doesn’t replicate and sometimes replicates seconds late.

I ended up going the changing the baseparts network ownership to server, and then changing state from there, and when I want the player to stand up just switch it back to player.

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