Player Loses Control of Character after Un-ragdolling

I have create (probably a rather bad) Ragdoll/Unragdoll Script while the player is alive.

game.Players.PlayerAdded:Connect(function(p)
	p.CharacterAdded:Connect(function(char)
	local mass = 0
	wait(10)
	char.Humanoid.BreakJointsOnDeath = false
		for _, v in pairs(char:GetDescendants()) do
			if v:IsA("Motor6D") then
				local vN = v.Parent.Name
				mass = v.Parent.Parent.PrimaryPart:GetMass()
				if vN ~= "RightHand" and vN ~= "LeftHand" and vN ~= "RightFoot" and vN ~= "LeftFoot" then
					print(vN)
					local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
					a0.CFrame = v.C0
					a1.CFrame = v.C1
					a0.Parent = v.Part0
					a1.Parent = v.Part1
								
					local b = Instance.new("BallSocketConstraint")
					b.LimitsEnabled = true
					b.UpperAngle = 60
					b.Restitution = 0
					b.TwistLimitsEnabled = true
					b.TwistLowerAngle = 0							
					b.TwistUpperAngle = 120
					if vN == "Head" then
						b.TwistUpperAngle = 60
					end
					if vN == "LowerTorso" then
						b.UpperAngle = 0
						b.TwistUpperAngle = 0
						b.TwistLowerAngle = 0
					end
					b.Attachment0 = a0
					b.Attachment1 = a1
					b.Parent = v.Part0
					v.Enabled = false
				end
			end
		end
		char.HumanoidRootPart.CanCollide = false
			
		p.Backpack.DisablePhysics.Value = true
			
		local bF = Instance.new("BodyForce", char.HumanoidRootPart)
		bF.Force = bF.Parent.CFrame:vectorToWorldSpace(Vector3.new(0, workspace.Gravity * 20 * mass, workspace.Gravity * -15 * mass))
		wait(0.2)
		bF.Force = bF.Parent.CFrame:vectorToWorldSpace(Vector3.new(0, 0 ,0))		
		
		wait(5)
		for _, v in pairs(char:GetDescendants()) do
			if v:IsA("Motor6D") then
				v.Enabled = true
			end
		end
		for _, v in pairs(char:GetDescendants()) do
			if v:IsA("BallSocketConstraint") and v.Name == "BallSocketConstraint" then
				local vN = v.Parent.Name
				--mass = v.Parent.Parent.PrimaryPart:GetMass()
				if vN ~= "RightHand" and vN ~= "LeftHand" and vN ~= "RightFoot" and vN ~= "LeftFoot" then
					v:Destroy()	
				end
			end
		end
		char.HumanoidRootPart.CanCollide = true
		p.Backpack.DisablePhysics.Value = false
		char.HumanoidRootPart.CFrame = CFrame.new(char.HumanoidRootPart.CFrame.X, char.HumanoidRootPart.CFrame.Y + 3.5, char.HumanoidRootPart.CFrame.Z)
		char.Humanoid:ChangeState(Enum.HumanoidStateType.Running)
	end)
end)
local mass = 0

Some of the script, i.e. Bodyforce, is just for testing. As well as the wait(n)'s.

My problem is, that after the Character Unragdolls, the player cannot do anything with the player.

As you may notice there is a BoolVal that is set, which does a :ChangeState on Physics, so that the Ragdoll actually works.

https://gyazo.com/f1a5e914a3816c6c6a8bc920d2253093

Are you sure you are changing the humanoid state back from Physics? What are you setting it to?

Setting the state type to something like Running or Freefalling will snap the humanoid back to reality.

I tried setting the Humanoid to Running and it just ran on the spot, with no control over it, it just ran, while fallen over ect…

After some additional testing since, it feels like the Player exists in the world, with the animations running, but as a generic model, not a Player, as the character sortof moves around a bit when an animation plays (i.e. Idle).

Can I see all of your code? That is, including the state toggle function?

The Main Script:

game.Players.PlayerAdded:Connect(function(p)
	p.CharacterAdded:Connect(function(char)
	local mass = 0
	wait(10)
	char.Humanoid.BreakJointsOnDeath = false
		for _, v in pairs(char:GetDescendants()) do
			if v:IsA("Motor6D") then
				local vN = v.Parent.Name
				mass = v.Parent.Parent.PrimaryPart:GetMass()
				if vN ~= "RightHand" and vN ~= "LeftHand" and vN ~= "RightFoot" and vN ~= "LeftFoot" then
					print(vN)
					local a0, a1 = Instance.new("Attachment"), Instance.new("Attachment")
					a0.CFrame = v.C0
					a1.CFrame = v.C1
					a0.Parent = v.Part0
					a1.Parent = v.Part1
								
					local b = Instance.new("BallSocketConstraint")
					b.LimitsEnabled = true
					b.UpperAngle = 60
					b.Restitution = 0
					b.TwistLimitsEnabled = true
					b.TwistLowerAngle = 0							
					b.TwistUpperAngle = 120
					if vN == "Head" then
						b.TwistUpperAngle = 60
					end
					if vN == "LowerTorso" then
						b.UpperAngle = 0
						b.TwistUpperAngle = 0
						b.TwistLowerAngle = 0
					end
					b.Attachment0 = a0
					b.Attachment1 = a1
					b.Parent = v.Part0
					v.Enabled = false
				end
			end
		end
		char.HumanoidRootPart.CanCollide = false
			
		p.Backpack.DisablePhysics.Value = true
			
		local bF = Instance.new("BodyForce", char.HumanoidRootPart)
		bF.Force = bF.Parent.CFrame:vectorToWorldSpace(Vector3.new(0, workspace.Gravity * 20 * mass, workspace.Gravity * -15 * mass))
		wait(0.2)
		bF.Force = bF.Parent.CFrame:vectorToWorldSpace(Vector3.new(0, 0 ,0))		
		
		wait(5)
		for _, v in pairs(char:GetDescendants()) do
			if v:IsA("Motor6D") then
				v.Enabled = true
			end
		end
		for _, v in pairs(char:GetDescendants()) do
			if v:IsA("BallSocketConstraint") and v.Name == "BallSocketConstraint" then
				local vN = v.Parent.Name
				--mass = v.Parent.Parent.PrimaryPart:GetMass()
				if vN ~= "RightHand" and vN ~= "LeftHand" and vN ~= "RightFoot" and vN ~= "LeftFoot" then
					v:Destroy()	
				end
			end
		end
		char.HumanoidRootPart.CanCollide = true
		p.Backpack.DisablePhysics.Value = false
		char.HumanoidRootPart.CFrame = CFrame.new(char.HumanoidRootPart.CFrame.X, char.HumanoidRootPart.CFrame.Y + 3.5, char.HumanoidRootPart.CFrame.Z)
	end)
end)
local mass = 0

The first For Loop (in Pairs) does the Ragdoll, then a Force is applied, then the second bit, reenabled all the Motor6D’s and deletes the BallSocketConstraint’s

and the other script

script.Parent.Changed:Connect(function()
	game.Players.LocalPlayer.Character.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
end)

Edit: script.Parent = BoolVal
Also: I removed the ChangeState for Running from the script as a test previously.

First of all, at the end, instead of setting the root part’s CFrame directly, use Model:SetPrimaryPartCFrame() on the character model. I am assuming you just want to pick the player up off the ground before re-enabling the character.

Secondly, it still doesn’t seem like you are ever changing the state from physics.

Replace your state toggle function with this, and see if it does what you need.

script.Parent.Changed:Connect(function(newValue)
    if newValue then
	    game.Players.LocalPlayer.Character.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
    else
        game.Players.LocalPlayer.Character.Humanoid:ChangeState(Enum.HumanoidStateType.FreeFall)
    end
end)

So I changed the script, as said and did the Model:SetPrimaryPartCFrame() but this: https://gyazo.com/feaecd52a70fb9101169bc7c4189f6b4 happened.

It worked, but I got the issue of Physics not being set.

Is p.Backpack.DisablePhysics a separate bool value? Or is it the second script’s parent bool value?

It is a seperate Bool Value, “physically” stored in the Backpack (because I’ve been using that for many Bools).

https://gyazo.com/2bdeff57c47614179d86bf54b5840cba

Make sure you are changing the value of the second script’s parent bool value. That is the one you should be changing if you want the state to be set.

p.Backpack.DisablePhysics.Value = false is that not what it’s doing?

All I do is read the value in the second script.

P.s. Sorry if I’m being dumb it’s like 1am ahah.

Get and store whichever bool value the second script is within, and change its value instead of the DisablePhysics bool in the backpack.

I can’t see your hierarchy, so its a little difficult for me to help with this part.

The Ragdoll Script is stored in ServerScriptStorage and DisablePhysics is in StarterPack.

Edit: I’m relatively new to Roblox and not sure what the best practises are, so I go with whatever I think is best.

Instead of saying p.Backpack.DisablePhysics.Value = true in the main script, say

WhateverTheSecondScriptsParentBool_Is.Value = true in the main script in place of the one above.

And the same for setting to false as well.

Thats all there is left for me to say.

It’s the same bool, the 2nd script is the Child of the Bool Value. Sorry, I just realised what you asked aha.
If that doesn’t help, thanks for all the help, you have got the script in a better version of itself than before, at least you can control the character after.

I changed the script that @KeysOfFate gave me to

script.Parent.Changed:Connect(function(newValue)
    if newValue then    game.Players.LocalPlayer.Character.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
    else
        game.Players.LocalPlayer.Character.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
    end
end)

This allowed the scripts to work.