Ragdoll not working correctly (NetworkOwnership issue)

I’ve made posts on this in the past, but i’ve finally found the root of the issue, I just can’t figure out a way to fix it. So, I have this ragdoll module that, well, ragdolls a player. When I fire this module on the client, the ragdoll works perfectly. But when it is fired by the server, the player does not fall and they hang off from the HumanoidRootPart.

Now, I would just fire from the client, but I want everyone to see the ragdolled player actually ragdolled, and when I fire from the client, it just shows a player stiff as a board on the ground instead of ragdolled to other players. I need to fire to the server, but without the HumanoidRootPart staying up, but how would I do this?

Fired from Client:
Screenshot 2024-08-01 145352
Fired from Server:
Screenshot 2024-08-01 145407
Servers view when fired from client:
Screenshot 2024-08-01 145421

giving network ownership of a part to a client makes the client’s changes replicated to the other clients

from the server, give network ownership of all the body parts to the client, then tell that client to move the ragdoll

1 Like

So would I do something like this?

for _, part in character:GetChildren() do
	if part:IsA("BasePart") and game:GetService("Players"):FindFirstChild(character.Name) then
		part:SetNetworkOwner(game:GetService("Players"):GetPlayerFromCharacter(character))
	end
end

When I do this, it errors when I fire the module from the client and still has the same behavior from when I would fire it from the server before this.

set the network ownership from the server

and then send a remote event to the client telling it to ragdoll the character

then ragdoll the character on the client

I think the code is working, but the remote event is not being fired. Here’s what the code looks like.

Module:

function RagdollModule:RagdollPlayer(character, duration)
    local humanoid = character:FindFirstChildOfClass("Humanoid")
    if not humanoid then
        return
    end
	
	local player = game:GetService("Players"):GetPlayerFromCharacter(character)
	
	if not player then
		return
	end
	
	for _, part in character:GetChildren() do
		if part:IsA("BasePart") then
			part:SetNetworkOwner(player)
		end
	end
	
	if player then
		player:FindFirstChild("ValuesFolder"):FindFirstChild("Stun").Value = true
	end
	
	if player then
		script.RagdollClientCommunicator:FireClient(player)
	end
	
	task.wait(duration)
	
	if player then
		player:FindFirstChild("ValuesFolder"):FindFirstChild("Stun").Value = false
	end
end

Client:

local Remote = script.Parent.RagdollClientCommunicator

Remote.OnClientEvent:Connect(function(character,duration)
	print("Run!")
	local humanoid = character:FindFirstChild("Humanoid")
	
	humanoid:ChangeState(Enum.HumanoidStateType.Physics)
	character.Humanoid.RequiresNeck = false 
	character.Humanoid.AutoRotate = false
	for index,joint in pairs(character:GetDescendants()) do
		if joint:IsA("Motor6D") then
			local socket = Instance.new("BallSocketConstraint")
			local a1 = Instance.new("Attachment")
			local a2 = Instance.new("Attachment")
			a1.Name = "RagdollAttach"
			a2.Name = "RagdollAttach"
			a1.Parent = joint.Part0
			a2.Parent = joint.Part1
			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

	task.wait(duration)

	for index,joint in pairs(character:GetDescendants()) do
		if joint:IsA("BallSocketConstraint") or joint.Name == "RagdollAttach" then
			joint:Destroy()
		end
	end

	for index,joint in pairs(character:GetDescendants()) do
		if joint:IsA("Motor6D") then
			joint.Enabled = true
		end
	end

	humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
	character.Humanoid.RequiresNeck = true
	character.Humanoid.AutoRotate = true
end)

There is no errors being thrown, so I will try to test this out without being in a module.

I tested this on a TextButton, having a server script run all of the module code.

The player did ragdoll, but on the server, the player was still stiff as a board.

Any help? I’ve been tinkering with it for a few hours and still haven’t been able to find a solution.

Still can’t figure this out, this is such a pain!

1 Like

I had this exact problem, and I fixed it disabling the animation like this, and firing an event to all clients to set the specific humanoid to a specific state, like this:

Server: (needs ragdollEnabled, character, and event defined)

character.Animate.Disabled = ragdollEnabled
if ragdollEnabled then
	for _,v in pairs(character.Humanoid:GetPlayingAnimationTracks()) do
		v:Stop(0)
	end
end
event:FireAllClients(character.Humanoid,(ragdollEnabled and Enum.HumanoidStateType.Physics or Enum.HumanoidStateType.GettingUp))

Client:

event.OnClientEvent:Connect(function(humanoid,state)
	humanoid:ChangeState(state)
end)

However, this would make it so you’d need to update all new clients who join AFTER the event is fired will need to know what state the humanoids are in.