Humanoid.BreakJointsOnDeath

I love this! :smiley:

I’m wondering how does the character fall? Is it pushed when it dies or is it some sort of an animation?

r2fall

61 Likes

It’s about time, hooray! :star_struck:

2 Likes

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.

25 Likes

Yes! I’ve been excited for this to be enabled!

2 Likes

Sounds like my kind of property!

On a serious note, this is nice because now I don’t have to clone their character to add death affects.

16 Likes

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.

190 Likes

Time to make an entire zombie game based on this feature.

14 Likes

What scary words. Okay, RespawnTime is next pls.

In other news, great property. At least we don’t have to hack joints to remain anymore, or anything. Easy ragdolls.

10 Likes

this just made custom deaths a whole lot easier. thanks!

5 Likes

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)
22 Likes

I am so excited to add ragdoll constraints to every single one of my custom characters. I can’t wait to see birds flopping out of the sky.

13 Likes

Another great update from our amazing Engineers! Thank you guys for your hard work!

2 Likes

Finally, I can successfully do the flop now. Life is complete, thank you for this.

11 Likes

Time to enable this in all of my games

3 Likes

nice ragdoll demo whoever record this

4 Likes

Great feature, smoother performance and easier to manage rag doll scripts. Can’t wait to use this in one of my projects. The comedic flopping effect is also a welcomed bonus.

4 Likes

Just add a wait(5) and :LoadCharacter() :smiley:

5 Likes

This is the obvious solution. I mean I would personally do wait(game:GetService(“Players”).RespawnTime) but whatever. I guess my question was why does it break re-spawning in the first place.

4 Likes

It seems like Humanoid :MoveTo() continues to function still, however it just sorta walks on its back and doesn’t move much other than flail around… fix?

https://gyazo.com/4722739474c4aa9379e1bc64d6130b1c

11 Likes

Looks like it’s time to bind a function to detect a Humanoid.Died event.

13 Likes