Ragdoll Problems

How can I make a ragdoll script that will not make the limbs of the rig go through floor when ragdoll, rig is not be able to walk while ragdoll, and not flinging when recover from ragdoll??

Script:

local function Ragdoll(Character: Model, RagdollType: string)
	assert(typeof(RagdollType) == 'string', `{OutputMark} RagdollType is not a valid string!!`)
	assert(typeof(Character) == 'Instance' and Character:IsA('Model') and Character:FindFirstChildWhichIsA('Humanoid'), `{OutputMark} Character is not a valid character!!`)
	
	local Humanoid = Character:WaitForChild('Humanoid')
	local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')
	
	if RagdollType == 'Run' then
		Humanoid.PlatformStand = true
		HumanoidRootPart.CanCollide = false
		
		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') then
				local Socket, A1, A2 = Instance.new('BallSocketConstraint', Obj.Parent), Instance.new("Attachment", Obj.Part0), Instance.new("Attachment", Obj.Part1)

				Socket:SetAttribute('RagdollAsset', '')
				A1:SetAttribute('RagdollAsset', '')
				A2:SetAttribute('RagdollAsset', '')

				A1.CFrame = Obj.C0
				A2.CFrame = Obj.C1

				Socket.Attachment0 = A1
				Socket.Attachment1 = A2
				Socket.LimitsEnabled = true
				Socket.TwistLimitsEnabled = true

				Obj.Enabled = false
			elseif Obj:IsA('BasePart') and Obj.Name ~= 'HumanoidRootPart' and not Obj.CanCollide then
				Obj:SetAttribute('RagdollAsset', '')
				Obj.CanCollide = true
			end
		end
	elseif RagdollType == 'Recover' then
		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') then
				Obj.Enabled = true
			elseif Obj:GetAttribute('RagdollAsset') then
				if Obj:IsA('BasePart') then
					if Obj.CanCollide then
						Obj.CanCollide = false
					end
				else
					Obj:Destroy()
				end
			end
		end
		
		Humanoid.PlatformStand = false
		HumanoidRootPart.CanCollide = true
	else
		warn(`{OutputMark} {RagdollType} type is not a valid ragdoll type!!`)
	end
end
7 Likes

For this you’d need to weld dummy parts to each of the character’s body parts when ragdolling. Make sure they’re smaller than the actual limbs so they don’t intersect weirdly with the other dummy parts

Try setting Humanoid.PlatformStand to true

Temporarily disable the HumanoidStateType.Ragdoll via humanoid:SetStateEnabled(Enum.HumanoidStateType.Ragdoll, false), then after some time set it back to true (I think it’s the ragdoll statetype that makes you fling but if this doesn’t make anything better let me know)

2 Likes

Ok, I will try this out!! Thanks for helping.

3 Likes

Hello there.

Apparently I already disabled the FallingDown and Ragdoll state but it seems like the fling not working. Also, how can I do the weld thingy you said??

2 Likes
local function Ragdoll(Character: Model, RagdollType: string)
	assert(typeof(RagdollType) == 'string', `{OutputMark} RagdollType is not a valid string!!`)
	assert(typeof(Character) == 'Instance' and Character:IsA('Model') and Character:FindFirstChildWhichIsA('Humanoid'), `{OutputMark} Character is not a valid character!!`)

	local Humanoid = Character:WaitForChild('Humanoid')
	local HumanoidRootPart = Character:WaitForChild('HumanoidRootPart')
	
	local BlacklistStates = {
		Enum.HumanoidStateType.Ragdoll;
		Enum.HumanoidStateType.FallingDown;
	}

	if RagdollType == 'Run' then
		
		for _, State in BlacklistStates do
			Humanoid:SetStateEnabled(State, false)
		end
		
		Humanoid.PlatformStand = true
		HumanoidRootPart.CanCollide = false

		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') then
				local Socket, A1, A2 = Instance.new('BallSocketConstraint', Obj.Parent), Instance.new("Attachment", Obj.Part0), Instance.new("Attachment", Obj.Part1)

				Socket:SetAttribute('RagdollAsset', '')
				A1:SetAttribute('RagdollAsset', '')
				A2:SetAttribute('RagdollAsset', '')

				A1.CFrame = Obj.C0
				A2.CFrame = Obj.C1

				Socket.Attachment0 = A1
				Socket.Attachment1 = A2
				Socket.LimitsEnabled = true
				Socket.TwistLimitsEnabled = true

				Obj.Enabled = false
			end
		end
	elseif RagdollType == 'Recover' then
		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') then
				Obj.Enabled = true
			elseif Obj:GetAttribute('RagdollAsset') then
				Obj:Destroy()
			end
		end

		Humanoid.PlatformStand = false
		HumanoidRootPart.CanCollide = true
		
		task.delay(3, function()
			print('Resetting state...')
			for _, State in BlacklistStates do
				Humanoid:SetStateEnabled(State, true)
			end
		end)
	else
		warn(`{OutputMark} {RagdollType} type is not a valid ragdoll type!!`)
	end
end
1 Like

Alright let’s try getting the flinging fixed first.

You doing this on R6 or R15 or is it a custom rig, and are you doing this on the server or the client? I’m trying right now and it’s not flinging me.

1 Like

Im doing this on server. I think that is the problem?

1 Like

Also, the limb going through floor is fixed. I did it!

1 Like

I think it could have something to do with you doing it on the server, it doesn’t look like SetStateEnabled replicates to the client (judging by this post). Since players have network ownership of their own character, these states would still be enterable.

Could you try firing a remote to the client telling them to disable these states instead of directly doing it on the server?

1 Like

Aight imma see it for myself. Thanks for helping me. I will post the solution here and credit u if I fixed.

1 Like

I think the states are already disabled.


image

1 Like


Forgot to remove the boolean from the method. But, the result are the same.

2 Likes

Ok that’s weird, you might just have to try seeing what state the humanoid is in when they get flung (listen to StateChanged)

The state is running when player get flung.
image


local function Ragdoll(Character: Model, RagdollType: string)
	assert(typeof(RagdollType) == 'string', `{OutputMark} RagdollType is not a valid string!!`)
	assert(typeof(Character) == 'Instance' and Character:IsA('Model') and Character:FindFirstChildWhichIsA('Humanoid'), `{OutputMark} Character is not a valid character!!`)

	local Humanoid: Humanoid = Character:WaitForChild('Humanoid')
	local HumanoidRootPart: BasePart = Character:WaitForChild('HumanoidRootPart')
	
	local BlacklistStates = {
		Enum.HumanoidStateType.Ragdoll;
		Enum.HumanoidStateType.FallingDown;
		Enum.HumanoidStateType.PlatformStanding;
	}
	
	if RagdollType == 'Run' then
		
		for _, State in BlacklistStates do
			Humanoid:SetStateEnabled(State, false)
		end
		
		Humanoid.PlatformStand = true
		HumanoidRootPart.CanCollide = false

		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') then
				local Socket, A1, A2 = Instance.new('BallSocketConstraint', Obj.Parent), Instance.new("Attachment", Obj.Part0), Instance.new("Attachment", Obj.Part1)

				Socket:SetAttribute('RagdollAsset', '')
				A1:SetAttribute('RagdollAsset', '')
				A2:SetAttribute('RagdollAsset', '')

				A1.CFrame = Obj.C0
				A2.CFrame = Obj.C1

				Socket.Attachment0 = A1
				Socket.Attachment1 = A2
				Socket.LimitsEnabled = true
				Socket.TwistLimitsEnabled = true

				Obj.Enabled = false
			elseif Obj:IsA('BasePart') then
				local NewObj = Instance.new('Part')
				NewObj.CFrame = Obj.CFrame
				NewObj.Size = Vector3.new(Obj.Size.X - 1, Obj.Size.Y - 1, Obj.Size.Z - 1)
				NewObj.CanCollide = true
				NewObj.Anchored = false
				NewObj.Transparency = 1
				NewObj.Name = 'CollisionPart'
				NewObj.Parent = Obj
				
				local NewWeld = Instance.new('WeldConstraint')
				NewWeld.Parent = NewObj
				NewWeld.Part0 = NewObj
				NewWeld.Part1 = Obj
				
				NewObj:SetAttribute('RagdollAsset', '')
			end
		end
		
		print(Humanoid:GetState())
		
	elseif RagdollType == 'Recover' then
		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') then
				Obj.Enabled = true
			elseif Obj:GetAttribute('RagdollAsset') then
				Obj:Destroy()
			end
		end

		Humanoid.PlatformStand = false
		HumanoidRootPart.CanCollide = true
		
		print(Humanoid:GetState())
		
		task.delay(3, function()
			print('Resetting state...')
			for _, State in BlacklistStates do
				Humanoid:SetStateEnabled(State, true)
			end
		end)
	else
		warn(`{OutputMark} {RagdollType} type is not a valid ragdoll type!!`)
	end
end
1 Like

Roblox is notorious for making changing collisions on body parts really difficult.

The way I fixed this is by going through each limb in the character and creating a smaller replica and welding it to its corresponding body part and using that as the collider instead of the actual limb. It’s a little jank but so far is the only way I’ve seen to do limb physics properly.

for _,v in pairs(char:GetChildren()) do --For i,v loop to go through all the objects in the char
	if v:IsA("MeshPart") then --Find all parts which are limbs since all limbs are meshes
		print(v) --Debugging
         --Create the part
		local CollisionPart = Instance.new("Part")
		CollisionPart.Parent = v
		CollisionPart.CFrame = v.CFrame 
		CollisionPart.Size = v.Size/2 --Setting the size smaller because if they're too big it acts buggy
		CollisionPart.Massless = true --Making sure we arent adding any extra weight to the character 				
		CollisionPart.Transparency = 0
		CollisionPart.Name = "COLLISION_PART"
		CollisionPart.CanCollide = false --Set to false when create, find all parts named Collision part and set collision to true when ragdoll happens
         --weld part to the corresponding body part
		local Weld = Instance.new("WeldConstraint",CollisionPart)
		Weld.Part0 = CollisionPart 
		Weld.Part1 = v 
	end
end
1 Like

Sorry for the late response, I was away.

That’s very odd. I’m wondering if you could limit the character’s velocity for about a second while they get up. See if adding this gives you any better results while getting up:

local now = os.clock()

while os.clock() - now < 1 do
    local velocity = HumanoidRootPart.AssemblyLinearVelocity
    
    if velocity.Magnitude > 15 then -- let's say they're moving at more than 15 studs per second,
        HumanoidRootPart.AssemblyLinearVelocity = velocity.Unit * 15
    end
end
2 Likes

Thank you for helping. I fixed it by disabling the states on client-side instead on server-side for player and for npc I set state on server.

local function Ragdoll(Character: Model, RagdollType: string)
	assert(typeof(RagdollType) == 'string', `{OutputMark} RagdollType is not a valid string!!`)
	assert(typeof(Character) == 'Instance' and Character:IsA('Model') and Character:FindFirstChildWhichIsA('Humanoid'), `{OutputMark} Character is not a valid character!!`)
	
	local Player = Players:GetPlayerFromCharacter(Character)
	
	local Humanoid: Humanoid = Character:WaitForChild('Humanoid')
	local HumanoidRootPart: BasePart = Character:WaitForChild('HumanoidRootPart')
	
	local BlacklistStates = {
		Enum.HumanoidStateType.FallingDown;
		Enum.HumanoidStateType.Ragdoll;
	}

	if RagdollType == 'Run' then
		if StateThread then
			task.cancel(StateThread)
		end
		
		HumanoidRootPart.CanCollide = false
		Humanoid.PlatformStand = true
		
		if Player then
			print('Fire to client')
			Replicator:FireClient(Player, 'SetClientHumanoidState', {
				States = {'FallingDown','Ragdoll'};
				SetType = false
			})
		else
			for _, State in BlacklistStates do
				Humanoid:SetStateEnabled(State, false)
			end
		end
		
		for _, Obj in Character:GetDescendants() do
			if Obj:IsA('Motor6D') then
				local Socket, A1, A2 = Instance.new('BallSocketConstraint', Obj.Parent), Instance.new("Attachment", Obj.Part0), Instance.new("Attachment", Obj.Part1)

				Socket:SetAttribute('RagdollAsset', '')
				A1:SetAttribute('RagdollAsset', '')
				A2:SetAttribute('RagdollAsset', '')

				A1.CFrame = Obj.C0
				A2.CFrame = Obj.C1

				Socket.Attachment0 = A1
				Socket.Attachment1 = A2
				Socket.LimitsEnabled = true
				Socket.TwistLimitsEnabled = true

				Obj.Enabled = false
			elseif Obj:IsA('BasePart') then
				local NewObj = Instance.new('Part')
				NewObj.CFrame = Obj.CFrame
				NewObj.Size = Vector3.new(Obj.Size.X - 1, Obj.Size.Y - 1, Obj.Size.Z - 1)
				NewObj.CanCollide = true
				NewObj.Anchored = false
				NewObj.Transparency = 1
				NewObj.Name = 'CollisionPart'
				NewObj.Parent = Obj

				local NewWeld = Instance.new('WeldConstraint')
				NewWeld.Parent = NewObj
				NewWeld.Part0 = NewObj
				NewWeld.Part1 = Obj

				NewObj:SetAttribute('RagdollAsset', '')
			end
		end
	elseif RagdollType == 'Recover' then
		for _, Obj in Character:GetDescendants() do
			if Obj:GetAttribute('RagdollAsset') then
				Obj:Destroy()
			elseif Obj:IsA('Motor6D') then
				Obj.Enabled = true
			end
		end
		
		HumanoidRootPart.CanCollide = true
		Humanoid.PlatformStand = false
		
		StateThread = task.delay(1, function()
			if Player then
				Replicator:FireClient(Player, 'SetClientHumanoidState', {
					States = {'FallingDown','Ragdoll'};
					SetType = true
				})
			else
				for _, State in BlacklistStates do
					Humanoid:SetStateEnabled(State, true)
				end
			end
		end)
	else
		warn(`{OutputMark} {RagdollType} type is not a valid ragdoll type!!`)
	end
end
1 Like

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