Hey Devforum! My players have long complained about ragdoll limbs clipping through parts (mainly ones that toggle their own CanCollide), and i wanted to know any ways i could prevent this. Perhaps pushing the limbs toward the torso until they aren’t clipping?
It might help if you migrate this topic over to Scripting Support as this issue appears to be related to issues with scripts. That way @Programmers can help you if they’re viewing your topic in that category/subcategory.
Oh, physics that could probably fit in Building Support, unless there’s an issue with scripts related to this in the game Scripting Support might still work.
You should create a part for each limb using :Clone(), then set .Size and .CFrame to same as the limb. then weld it to the limb, set massless to true and parent it:
(Roblox doesnt alllow .CanCollide set to true for limbs)
local sizeScale = 0.75 --Fine Control
local function createCollider(limb:BasePart)
--//Create a invisible part that creates the effect as if the given limb has collision
local collider = Instance.new("Part")
collider.CFrame = limb.CFrame
collider.Massless = true
collider.Size = limb.Size * sizeScale
collider.Transparency = 1
--//Create a weld so the collider remains fixed at the limb
local weld = Instance.new("WeldConstraint")
weld.Part0 = collider
weld.Part1 = limb
weld.Parent = collider
--//Finalize
collider:AddTag("collider") --So we can easily destroy it later
collider.Parent = limb
return collider --Not necessary, but why not
--
end
--//Example usecase:
local function ragdoll(character:Model, state)
--
if state == true then
--
for _, limb in character:GetDescendants() do
--//Create a collider for each limb
if not limb:IsA("BasePart") then continue end
createCollider(limb)
end
--
elseif state == false then
--
for _, collider in character:GetDescendants() do
--//Destroy each collider
if not collider:HasTag("collider") then continue end
collider:Destroy()
--
end
--
--//Rest of your ragdoll script here:
end
(I wrote this on mobile, be aware of errors and/ or bugs)
(I am happy your game is turning out so well, I hope this helps )
sure (the createCollider function is what you shared, i just removed the parts that used it)
local module = {}
local Players = game:GetService("Players")
local PhysicsService = game:GetService("PhysicsService")
local ragParts = script.Parent.RagdollParts:GetChildren()
local function createCollider(limb : BasePart)
local collider = Instance.new("Part")
collider.CFrame = limb.CFrame
collider.Massless = true
collider.Size = limb.Size
collider.Transparency = 1
local weld = Instance.new("WeldConstraint")
weld.Part0 = collider
weld.Part1 = limb
weld.Parent = collider
collider:AddTag("Collider")
collider.Name = limb.Name .. " Collider"
collider.Parent = limb.Parent
return collider
end
function module:Setup(char : Model, isPlayer)
if not char.Humanoid then return end
local humanoid = char:FindFirstChild("Humanoid")
assert(humanoid, "Can only set-up ragdoll on R6 humanoid rigs")
assert(humanoid.RigType == Enum.HumanoidRigType.R6, "Can only set-up ragdoll on R6 humanoid rigs")
assert(humanoid.RootPart ~= nil, "No RootPart was found in the provided rig")
assert(char:FindFirstChild("HumanoidRootPart"), "No HumanoidRootPart was found in the provided rig")
if not isPlayer then
for _, v: BasePart in ipairs(char:GetDescendants()) do
if v:IsA("BasePart") then
v:SetNetworkOwner(nil)
end
end
end
-- Setup ragdoll
char.Head.Size = Vector3.new(1, 1, 1)
humanoid.BreakJointsOnDeath = false
humanoid.RequiresNeck = true
local clones = {}
for _, v in ipairs(ragParts) do
clones[v.Name] = v:Clone()
end
local folder1 = Instance.new("Folder")
folder1.Name = "RagdollConstraints"
for _, v in pairs(clones) do
if v:IsA("Attachment") then
v.Parent = char[v:GetAttribute("Parent")]
elseif v:IsA("BallSocketConstraint") then
v.Attachment0 = clones[v:GetAttribute("0")]
v.Attachment1 = clones[v:GetAttribute("1")]
v.Parent = folder1
end
end
folder1.Parent = char
local folder2 = Instance.new("Folder")
folder2.Name = "Motors"
local value
for _, v in ipairs(char.Torso:GetChildren()) do
if v:IsA("Motor6D") then
value = Instance.new("ObjectValue")
value.Value = v
value.Parent = folder2
end
end
folder2.Parent = folder1
-- Ragdoll trigger
local trigger = Instance.new("BoolValue")
trigger.Name = "RagdollTrigger"
trigger.Parent = char
trigger.Changed:Connect(function(bool)
if bool then
module:Ragdoll(char)
else
module:Unragdoll(char)
end
end)
end
function module:Ragdoll(char: Model)
if not char.Humanoid then return end
char.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
char.Humanoid.AutoRotate = false
for _, v in ipairs(char.RagdollConstraints.Motors:GetChildren()) do
v.Value.Enabled = false
end
for _, v in ipairs(char:GetChildren()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Ragdoll"
end
end
local hrp = char:FindFirstChild("HumanoidRootPart")
local rootJoint = hrp:FindFirstChildOfClass("Motor6D")
if rootJoint then
rootJoint.Enabled = false
end
hrp:ApplyAngularImpulse(Vector3.new(-90, 0, 0))
end
function module:Unragdoll(char: Model)
if not char.Humanoid then return end
char.Humanoid:ChangeState(Enum.HumanoidStateType.GettingUp)
for _, v in ipairs(char.RagdollConstraints.Motors:GetChildren()) do
v.Value.Enabled = true
end
for _, v in ipairs(char:GetChildren()) do
if v:IsA("BasePart") then
v.CollisionGroup = "Default"
end
end
local hrp = char:FindFirstChild("HumanoidRootPart")
local rootJoint = hrp:FindFirstChildOfClass("Motor6D")
if rootJoint then
rootJoint.Enabled = true
end
char.Humanoid.AutoRotate = true
end
return module
have you tried making an invisible part where the door is located, use collisiongroup so only the bodies collide with it and turn .CanCollide only true when closing the door?