Wierd behaviour with ChangeState and the Humanoid

In short, I’m trying to create a ragdoll with this bit of code:

rbvalue.Changed:Connect(function()
	if rbvalue.Value then

		-- Init
		
		local humanoidRootPart = char:WaitForChild("HumanoidRootPart")
		local humanoid = char:WaitForChild("Humanoid")
		humanoid.BreakJointsOnDeath = false
		humanoid.RequiresNeck = false
		
		-- Check for joints
		for i, v in pairs(char:GetDescendants()) do
			if v:IsA("Motor6D") then

				-- Create attachments
				local socket = Instance.new("BallSocketConstraint")
				local a1 = Instance.new("Attachment")
				local a2 = Instance.new("Attachment")
				a1.Parent = v.Part0
				a2.Parent = v.Part1
				socket.Parent = v.Parent
				socket.Attachment0 = a1
				socket.Attachment1 = a2
				a1.CFrame = v.C0
				a2.CFrame = v.C1

				-- Set constraints
				socket.LimitsEnabled = true
				socket.TwistLimitsEnabled = true

				v.Enabled = false

				humanoid:ChangeState(Enum.HumanoidStateType.Ragdoll)
			end
		end



	elseif not rbvalue.Value then

		rbvalue.Value = false

		-- Remove ragdolls
		humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)


		for i, v in pairs(char:GetDescendants()) do
			if v:IsA("BallSocketConstraint") then

				v:Destroy()

			elseif v:IsA("Motor6D") then

				v.Enabled = true

			end
		end
	end
end)

Although this code works near flawlessly, The ragdolled player can still walk around just fine, although ragdolled (obviously). Now, there is a simple fix to this, and that’s Humanoid.PlatformStand = true. However, platform stand comes with the side effect of limbs clipping into the ground and I don’t want that but I have no clue as to why the ragdoll state doesn’t have my character unable to move. Any ideas?

image

try setting this to Enum.HumanoidStateType.Physics

1 Like

Hmm. It doesn’t work but I don’t believe its because of the state type. I tagged a line after humanoid:ChangeState(Enum.HumanoidStateType.Physics) so it looked like this:

print(humanoid:GetState())

but i get this in the console:

Enum.HumanoidStateType.Running

It doesn’t change at all even though there doesn’t seem too be any logic to prevent that. If it helps, the ragdoll code is handled by a server script.

It sounds like you may be missing a step in your code. When you change the Humanoid’s state to Ragdoll, you need to also set the Humanoid’s PlatformStand property to true. This will prevent the character from being able to move while in the ragdoll state.

You can do this by adding the following line of code after you set the Humanoid’s BreakJointsOnDeath and RequiresNeck properties:

humanoid.PlatformStand = true
1 Like

I’ve considered this. The only problem I have with platformstand is that it sets the limbs to no collide, creating a weird effect where the limbs clip through the floor. I believe the issue lies in the ChangeState() method not working. I’m trying to solve this right now.

Edit: I’ve also tried adding char.HumanoidRootPart:SetNetworkOwner(nil) before the state is changed. No effect :frowning:

This is what the new script looks like:

rbvalue.Changed:Connect(function()
	if rbvalue.Value then

		-- Init
		
		char.HumanoidRootPart:SetNetworkOwner(nil)

		humanoid:ChangeState(Enum.HumanoidStateType.Physics)
		print(humanoid:GetState())
		
		local humanoidRootPart = char:WaitForChild("HumanoidRootPart")
		local humanoid = char:WaitForChild("Humanoid")
		humanoid.BreakJointsOnDeath = false
		humanoid.RequiresNeck = false
		
		-- Check for joints
		for i, v in pairs(char:GetDescendants()) do
			if v:IsA("Motor6D") then

				-- Create attachments
				local socket = Instance.new("BallSocketConstraint")
				local a1 = Instance.new("Attachment")
				local a2 = Instance.new("Attachment")
				a1.Parent = v.Part0
				a2.Parent = v.Part1
				socket.Parent = v.Parent
				socket.Attachment0 = a1
				socket.Attachment1 = a2
				a1.CFrame = v.C0
				a2.CFrame = v.C1

				-- Set constraints
				socket.LimitsEnabled = true
				socket.TwistLimitsEnabled = true

				v.Enabled = false
			end
		end



	elseif not rbvalue.Value then

		rbvalue.Value = false

		-- Remove ragdolls
		humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
		
		char.HumanoidRootPart:SetNetworkOwner(player)

		for i, v in pairs(char:GetDescendants()) do
			if v:IsA("BallSocketConstraint") then

				v:Destroy()

			elseif v:IsA("Motor6D") then

				v.Enabled = true

			end
		end
	end
end)

The humanoid state type is still “Running”

I think the issue is that the ChangeState() method is not working properly. I suggest trying to use a different method to change the humanoid state, such as humanoid:ChangeState(Enum.HumanoidStateType.PlatformStanding). This should set the limbs to no collide and prevent the limbs from clipping through the floor.

Apparently PlatformStanding is deprecated or is read only (You can only check if the humanoid is platformstaning with GetState(). But how is that meant to healp when the ChangeState() method itself doesn’t work?

I forgot an important part which is that the client has network ownership of the character so any changes you try to make to the humanoid using the server will be overwritten by the client.

My other comment that i deleted i recommended using :SetNetworkOwner() to set the server to the owner of humanoidRootPart, but i think a better solution is to use a RemoteEvent to get the client to change the humanoid state to physics.

So inside the server script you would have something like

game.ReplicatedStorage.RagdollRemote:FireClient(player, true)

for enabling ragdoll, and

game.ReplicatedStorage.RagdollRemote:FireClient(player, false)

for disabling.

then in a local script in StarterCharacterScripts you could have

local char = script.Parent

game.ReplicatedStorage.RagdollRemote.OnClientEvent:Connect(function(enable)
    if enable then
        char.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
    else
        char.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
    end
end)

try that and let me know if/how it works

1 Like

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