How do I improve this controllable ragdoll?

Below is a link with a video of how it works at the moment (you’ll probably have to copy the link)

External Media

So, i want to:

  • Make it more stable
  • Make it more “efficient”
  • And any of your own ideas.
Scripts
-- Local script
local uis = game:GetService("UserInputService")
local act

local character = script.Parent.Parent.Parent

uis.InputBegan:Connect(function(input)
	if character.IsRagdolled.Value == true then
		if input.UserInputType == Enum.UserInputType.MouseButton2 then
			act = "RightEn"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			act = "LeftEn"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.KeyCode == Enum.KeyCode.Q then
			act = "LeftClEn"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.KeyCode == Enum.KeyCode.E then
			act = "RightClEn"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.KeyCode == Enum.KeyCode.W then
			act = "Crawl"
			script.Parent.InputReciever:FireServer(act)
		end
	end
end)

uis.InputEnded:Connect(function(input)
	if character.IsRagdolled.Value == true then
		if input.UserInputType == Enum.UserInputType.MouseButton2 then
			act = "RightDis"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			act = "LeftDis"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.KeyCode == Enum.KeyCode.Q then
			act = "LeftClDis"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.KeyCode == Enum.KeyCode.E then
			act = "RightClDis"
			script.Parent.InputReciever:FireServer(act)
		end
		if input.KeyCode == Enum.KeyCode.W then
			act = "CrawlDis"
			script.Parent.InputReciever:FireServer(act)
		end
	end
end)

character.IsRagdolled:GetPropertyChangedSignal("Value"):Connect(function()
	if character.IsRagdolled.Value == false then
		act = "RightDis"
		script.Parent.InputReciever:FireServer(act)
		act = "LeftDis"
		script.Parent.InputReciever:FireServer(act)
		act = "RightClDis"
		script.Parent.InputReciever:FireServer(act)
		act = "LeftClDis"
		script.Parent.InputReciever:FireServer(act)
		act = "CrawlDis"
		script.Parent.InputReciever:FireServer(act)
	end
end)

-- Server script

local char = script.Parent.Parent.Parent
local RHandAtt = Instance.new("Attachment")
RHandAtt.Parent = char.RightHand
script.Parent.RArm.RArmAlign.Attachment0 = RHandAtt
script.Parent.RArm.RArmAlign.Attachment1 = script.Parent.Parent.RArmAtt
local LHandAtt = Instance.new("Attachment")
LHandAtt.Parent = char.LeftHand
script.Parent.LArm.LArmAlign.Attachment0 = LHandAtt
script.Parent.LArm.LArmAlign.Attachment1 = script.Parent.Parent.LArmAtt
local TorsoAtt = Instance.new("Attachment")
TorsoAtt.Parent = char.Head
script.Parent.Torso.TorsoAlign.Attachment0 = TorsoAtt
script.Parent.Torso.TorsoAlign.Attachment1 = script.Parent.Parent.TorsoAtt


local rhand = char:FindFirstChild("RightHand")
local lhand = char:FindFirstChild("LeftHand")

script.Parent.LArm.DragIcon.Parent = lhand
script.Parent.RArm.DragIcon.Parent = rhand

script.Parent.LArm.GrabSound.Parent = lhand
script.Parent.RArm.GrabSound.Parent = rhand

local curR
local curL

local curAttR
local curAttL

local ClR = false
local ClL = false

script.Parent.InputReciever.OnServerEvent:Connect(function(plr: Player, act)
	if act == "RightEn" then
		script.Parent.RArm.RArmAlign.Enabled = true
	elseif act == "RightDis" then
		script.Parent.RArm.RArmAlign.Enabled = false	
	elseif act == "LeftEn" then
		script.Parent.LArm.LArmAlign.Enabled = true
	elseif act == "LeftDis" then
		script.Parent.LArm.LArmAlign.Enabled = false	
	end
	if act == "RightClEn" then
		local rtps = rhand:GetTouchingParts()
		for i, v in pairs(rtps) do
			if v.CanCollide == true and v.CanTouch == true and v.Parent ~= char and v.Parent.Parent ~= char then
				if not rhand:FindFirstChild("RBallS") then
					if v.Parent:FindFirstChild("IsRagdolled") then
						local vplr = game.Players:GetPlayerFromCharacter(v.Parent)
						vplr.PlayerGui.ragdoll.functions.ragdoll:Invoke(Vector3.new(0, 0, 0))
					end
					rhand.GrabSound:Play()
					script.Parent.RArm.RArmAlign.Responsiveness = 0
					ClR = true
					curR = v
					rhand.DragIcon.Enabled = true
					local rballsoc = Instance.new("BallSocketConstraint")
					local rnewatt = Instance.new("Attachment")
					rballsoc.Parent = rhand
					rnewatt.Parent = v
					rnewatt.Name = "ClimbAttachmentR"
					rnewatt.WorldPosition = rhand.Position
					curAttR = rnewatt
					rballsoc.LimitsEnabled = true
					rballsoc.TwistLimitsEnabled = true
					rballsoc.UpperAngle = 25
					rballsoc.TwistLowerAngle = -25
					rballsoc.TwistUpperAngle = 25
					rballsoc.Name = "RBallS"
					rballsoc.Attachment0 = RHandAtt
					rballsoc.Attachment1 = rnewatt
				end
			end
		end
	elseif act == "RightClDis" then
		if rhand:FindFirstChild("RBallS") then
			rhand.GrabSound:Play()
			script.Parent.RArm.RArmAlign.Responsiveness = 20
			ClR = false
			rhand.RBallS:Destroy()
			curAttR:Destroy()
			curAttR = nil
			curR = nil
			rhand.DragIcon.Enabled = false
		end	
	end
	if act == "LeftClEn" then
		local ltps = lhand:GetTouchingParts()
		for i, v in pairs(ltps) do
			if v.CanCollide == true and v.CanTouch == true and v.Parent ~= char and v.Parent.Parent ~= char then
				if not lhand:FindFirstChild("LBallS") then
					if v.Parent:FindFirstChild("IsRagdolled") then
						local vplr = game.Players:GetPlayerFromCharacter(v.Parent)
						vplr.PlayerGui.ragdoll.functions.ragdoll:Invoke(Vector3.new(0, 0, 0))
					end
					lhand.GrabSound:Play()
					script.Parent.LArm.LArmAlign.Responsiveness = 0
					ClL = true
					curL = v
					lhand.DragIcon.Enabled = true
					local lballsoc = Instance.new("BallSocketConstraint")
					local lnewatt = Instance.new("Attachment")
					lballsoc.Parent = lhand
					lnewatt.Parent = v
					lnewatt.Name = "ClimbAttachmentL"
					lnewatt.WorldPosition = lhand.Position
					curAttL = lnewatt
					lballsoc.LimitsEnabled = true
					lballsoc.TwistLimitsEnabled = true
					lballsoc.UpperAngle = 25
					lballsoc.TwistLowerAngle = -25
					lballsoc.TwistUpperAngle = 25
					lballsoc.Name = "LBallS"
					lballsoc.Attachment0 = LHandAtt
					lballsoc.Attachment1 = lnewatt
				end
			end
		end
	elseif act == "LeftClDis" then
		if lhand:FindFirstChild("LBallS") then
			lhand.GrabSound:Play()
			script.Parent.LArm.LArmAlign.Responsiveness = 20
			ClL = false
			lhand.LBallS:Destroy()
			curAttL:Destroy()
			curAttL = nil
			curL = nil
			lhand.DragIcon.Enabled = false
		end
	elseif act == "Crawl" then
		if ClR == true or ClL == true then
			script.Parent.Torso.TorsoAlign.Enabled = true
		end
	elseif act == "CrawlDis" then
		script.Parent.Torso.TorsoAlign.Enabled = false
	end
	game:GetService("RunService").Heartbeat:Connect(function()
		if ClR == false and ClL == false then
			script.Parent.Torso.TorsoAlign.Enabled = false
		end
	end)
end)

I used free ragdoll system and supplemented it with this control, I don’t remember the author of the original ragdoll.

If I did something wrong or forgot, please tell me, this is my first time creating a topic.

4 Likes

Replace: if character.IsRagdolled.Value (this is the same thing. It’s called a truthy value.)

Replace these with table references.

local actionBinds= {
   [Enum.UserInputType.MouseButton2] = "RightEn",
   [Enum.UserInputType.MouseButton1] = "LeftEn",
   [Enum.KeyCode.Q] = "Enum.KeyCode.Q"
}

uis.InputBegan:Connect(function(input)
   if not character.IsRagdolled.Value then return end

   local action = actionBindings[input.UserInputType] or actionBindings[input.KeyCode]
   act = action
   script.Parent.InputReciever:FireServer(act)
end)

Do this same stuff for the InputEnded.

Will add more stuff when I get home. This should clean up your code just slightly.

1 Like

Thank you for this help, I didn’t know the code could be shortened this way lol. I’ll do this as soon as I finish my break from coding.