Howdy fellow Roblox devs! I have been working on this for a while, and I can’t really seem to find out a good solution. I have been trying to make an R6 ragdoll for a stealth game that I want to make; However, there are a few things that I’m having issues with. The first is client-server replication. What should the server handle and take care of? And vice versa for the client? stuff like that, and I have been trying to make it work for players and NPCs alike, although I am really struggling with implementing this. Here is the module script I have written (if anyone cares to read it):
local module = {}
local UIS = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local events = ReplicatedStorage:WaitForChild("Events")
local changeStateEvent = events:WaitForChild("ChangeState")
function module.CreateAttachments(char)
local attachments = {}
local torso = char:WaitForChild("Torso")
local head = char:WaitForChild("Head")
local rightArm = char:WaitForChild("Right Arm")
local leftArm = char:WaitForChild("Left Arm")
local rightLeg = char:FindFirstChild("Right Leg")
local leftLeg = char:FindFirstChild("Left Leg")
local rootPart = char:WaitForChild("HumanoidRootPart")
local rata = Instance.new("Attachment", torso)
rata.Name = "RightArmTorsoAttachment"
rata.Position = Vector3.new(1, 1, 0)
table.insert(attachments,rata)
local lata = Instance.new("Attachment", torso)
lata.Name = "LeftArmTorsoAttachment"
lata.Position = Vector3.new(-1, 1, 0)
table.insert(attachments,lata)
local rlta = Instance.new("Attachment", torso)
rlta.Name = "RightLegTorsoAttachment"
rlta.Position = Vector3.new(0.5, -1, 0)
table.insert(attachments,rlta)
local llta = Instance.new("Attachment", torso)
llta.Name = "LeftLegTorsoAttachment"
llta.Position = Vector3.new(-0.5, -1, 0)
table.insert(attachments,llta)
local raa = Instance.new("Attachment", char["Right Arm"])
raa.Name = "RightArmAttachment"
raa.Position = Vector3.new(-0.5, 1, 0)
table.insert(attachments,raa)
local laa = Instance.new("Attachment", char["Left Arm"])
laa.Name = "LeftArmAttachment"
laa.Position = Vector3.new(0.5, 1, 0)
table.insert(attachments,laa)
local rlaa = Instance.new("Attachment", rightLeg)
rlaa.Name = "RightLegAttachment"
rlaa.Position = Vector3.new(0, 1, 0)
table.insert(attachments,rlaa)
local llaa = Instance.new("Attachment", leftLeg)
llaa.Name = "LeftLegAttachment"
llaa.Position = Vector3.new(0, 1, 0)
table.insert(attachments,llaa)
local ha = Instance.new("Attachment", char.Head)
ha.Name = "HeadAttachment"
ha.Position = Vector3.new(0, -0.5, 0)
table.insert(attachments,ha)
print('finish')
end
function module.ragdoll(char)
local torso = char:FindFirstChild("Torso")
local head = char:FindFirstChild("Head")
local rightArm = char:FindFirstChild("Right Arm")
local leftArm = char:FindFirstChild("Left Arm")
local rightLeg = char:FindFirstChild("Right Leg")
local leftLeg = char:FindFirstChild("Left Leg")
local rootPart = char:FindFirstChild("HumanoidRootPart")
if char and char:FindFirstChild("Humanoid") then
local humanoid = char:FindFirstChild("Humanoid")
humanoid.RequiresNeck = false
for _, part in pairs(char:GetDescendants()) do
if part:IsA("Part") then
local customPhysicalProperties = PhysicalProperties.new(0.75, 0.5, 0.5, 0.75, 1)
part.CustomPhysicalProperties = customPhysicalProperties
end
end
for i, v in pairs(humanoid:GetPlayingAnimationTracks()) do
v:Stop()
end
local charTable = {
torso,
head,
rightArm,
leftArm,
rightLeg,
leftLeg,
rootPart
}
for _, part in ipairs(charTable) do
if part:IsA("BasePart") and part ~= char.HumanoidRootPart and part ~= torso then
local joint = Instance.new("BallSocketConstraint")
joint.Parent = part
joint.Enabled = true
joint.Visible = true
joint.LimitsEnabled = true
if part.Name == "Right Arm" then
joint.Attachment0 = torso:FindFirstChild("RightArmTorsoAttachment")
joint.Attachment1 = rightArm:FindFirstChild("RightArmAttachment")
joint.TwistLowerAngle = -45
joint.TwistUpperAngle = 90
joint.UpperAngle = 90
joint.TwistLimitsEnabled = true
elseif part.Name == "Left Arm" then
joint.Attachment0 = torso:FindFirstChild("LeftArmTorsoAttachment")
joint.Attachment1 = leftArm:FindFirstChild("LeftArmAttachment")
joint.TwistLowerAngle = -90
joint.TwistUpperAngle = 45
joint.UpperAngle = 90
joint.TwistLimitsEnabled = true
elseif part.Name == "Right Leg" then
joint.Attachment0 = torso:FindFirstChild("RightLegTorsoAttachment")
joint.Attachment1 = rightLeg:FindFirstChild("RightLegAttachment")
joint.TwistLowerAngle = -20
joint.TwistUpperAngle = 0
joint.UpperAngle = 20
joint.TwistLimitsEnabled = true
elseif part.Name == "Left Leg" then
joint.Attachment0 = torso:FindFirstChild("LeftLegTorsoAttachment")
joint.Attachment1 = leftLeg:FindFirstChild("LeftLegAttachment")
joint.TwistLowerAngle = -20
joint.TwistUpperAngle = 0
joint.UpperAngle = 20
joint.TwistLimitsEnabled = true
elseif part.Name == "Head" then
joint.Attachment0 = torso.NeckAttachment
joint.Attachment1 = head:FindFirstChild("HeadAttachment")
joint.TwistLowerAngle = -45
joint.TwistUpperAngle = 45
joint.UpperAngle = 45
joint.TwistLimitsEnabled = true
joint.LimitsEnabled = false
end
joint.Restitution = 0
end
end
if torso then
for i, v in pairs(torso:GetChildren()) do
if v:IsA("Motor6D") then
v.Enabled = false
end
end
torso.Velocity = Vector3.new(torso.Velocity.X, torso.Velocity.Y + 50, torso.Velocity.Z)
end
end
end
function unragdoll(char,player)
local torso = char:FindFirstChild("Torso")
local head = char:FindFirstChild("Head")
local rightArm = char:FindFirstChild("Right Arm")
local leftArm = char:FindFirstChild("Left Arm")
local rightLeg = char:FindFirstChild("Right Leg")
local leftLeg = char:FindFirstChild("Left Leg")
local rootPart = char:FindFirstChild("HumanoidRootPart")
local humanoid = char:FindFirstChild("Humanoid")
if player then
changeStateEvent:FireClient(player,Enum.HumanoidStateType.GettingUp)
else
humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
end
for i, v in pairs(torso:GetChildren()) do
if v:IsA("Motor6D") then
v.Enabled = true
end
end
for _, part in ipairs(char:GetDescendants()) do
if part:IsA("BallSocketConstraint") then
part:Destroy()
end
end
humanoid.RequiresNeck = true
end
return module
Obviously it’s pretty long so in summary it just makes attachments and provides the code for ragdolling characters and npcs, as well as unragdolling. Thank you in advance to all help from everybody. If something is unclear or needs clarifying, please feel free to ask! Thank you for looking!