Just enabled a new property of Humanoid, BreakJointsOnDeath.
When set to true, your avatar breaks into pieces on death. This is how it has always worked until today.
When set to false, your avatar is not affected by death. You become a cold, unfeeling immortal.
This makes writing ragdoll-on-death scripts substantially easier, since you can now use rigid joints in your ragdoll rigs without them breaking off.
Biggest benefit: Ragdolls can easily keep their hats. And hair.
There’s a small performance benefit to this too. No more scanning the list of joints for every avatar part every frame looking for joints to break. Now you can do it once and be done.
This is awesome! A simple ragdoll script is as easy as this now:
local died
died = character.Humanoid.Died:Connect(function()
local d = character:GetDescendants()
for i=1,#d do
local desc = d[i]
if desc:IsA("Motor6D") then
local socket = Instance.new("BallSocketConstraint")
local part0 = desc.Part0
local joint_name = desc.Name
local attachment0 = desc.Parent:FindFirstChild(joint_name.."Attachment") or desc.Parent:FindFirstChild(joint_name.."RigAttachment")
local attachment1 = part0:FindFirstChild(joint_name.."Attachment") or part0:FindFirstChild(joint_name.."RigAttachment")
if attachment0 and attachment1 then
socket.Attachment0, socket.Attachment1 = attachment0, attachment1
socket.Parent = desc.Parent
desc:Destroy()
end
end
end
end)
Previously you had to do a lot of welding for accessories, etc.
Here is a rag doll script I just made. It lets you customize which constraint to use between joints and it also lets you customize the properties of each constraint. Unfortunately, it breaks re-spawning and I have no idea why. Maybe some one knows? Anyways, have fun:
local Players = game:GetService("Players")
local JOINT_CONFIGURATION = {
LeftAnkle = {
"Hinge";
Properties = {
LimitsEnabled = true;
UpperAngle = 15;
LowerAngle = -45;
};
};
RightAnkle = {
"Hinge";
Properties = {
LimitsEnabled = true;
UpperAngle = 15;
LowerAngle = -45;
};
};
LeftKnee = {
"Hinge";
Properties = {
LimitsEnabled = true;
UpperAngle = 0;
LowerAngle = -75;
};
};
RightKnee = {
"Hinge";
Properties = {
LimitsEnabled = true;
UpperAngle = 0;
LowerAngle = -75;
};
};
LeftHip = {"BallSocket"};
RightHip = {"BallSocket"};
Waist = {"BallSocket"};
LeftShoulder = {"BallSocket"};
RightShoulder = {"BallSocket"};
LeftElbow = {"BallSocket"};
RightElbow = {"BallSocket"};
LeftWrist = {
"Hinge";
Properties = {
LimitsEnabled = true;
UpperAngle = 0;
LowerAngle = 0;
};
};
RightWrist = {
"Hinge";
Properties = {
LimitsEnabled = true;
UpperAngle = 0;
LowerAngle = 0;
};
};
Neck = {"BallSocket"};
}
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
character:WaitForChild("Humanoid").Died:Connect(function(humanoid)
character.HumanoidRootPart.Anchored = true
character.HumanoidRootPart.CanCollide = false
character.HumanoidRootPart:BreakJoints()
for _,desc in pairs(character:GetDescendants()) do
if (desc:IsA("Motor6D") and JOINT_CONFIGURATION[desc.Name]) then
local Joint = Instance.new(JOINT_CONFIGURATION[desc.Name][1] .. "Constraint")
local Attachment0 = desc.Parent:FindFirstChild(desc.Name .. "Attachment") or desc.Parent:FindFirstChild(desc.Name .. "RigAttachment")
local Attachment1 = desc.Part0:FindFirstChild(desc.Name .. "Attachment") or desc.Part0:FindFirstChild(desc.Name .. "RigAttachment")
if (JOINT_CONFIGURATION[desc.Name].Properties) then
for property,value in pairs(JOINT_CONFIGURATION[desc.Name].Properties) do
Joint[property] = value
end
end
if (Attachment0 and Attachment1) then
Joint.Attachment0 = Attachment0
Joint.Attachment1 = Attachment1
Joint.Parent = desc.Parent
desc:Destroy()
end
elseif (desc:IsA("Attachment")) then
desc.Axis = Vector3.new(0, 1, 0)
desc.SecondaryAxis = Vector3.new(0, 0, 1)
desc.Rotation = Vector3.new(0, 0, 0)
end
end
end)
end)
end)