How would i be able to detach limbs

I’m currently making a system whenever you shoot the player at their limbs, the players limbs fall to the ground after. however there is a slight issue whenever I remove the joint/moter6d; it basically falls into the void, i also tried to parent the limb to the workspace, by doing that it’ll loose its texture and shading and it looks like a regular part

5 Likes

Was going to suggest destroying the motor, but then saw you said that lol

idk, I’m interested in that too now

1 Like

I’ve found a hacky solution to this,
make a separate model with the humanoid (and clothing if character has clothes)
next parent the body part to the model
turn on can collide for part
delete the joint/motor6d
image

here’s the script if ur lazy i placed it under starter character scripts

task.wait(5)

local char = script.Parent
local part = char["Right Arm"];

local model = Instance.new("Model");
model.Parent = workspace;

local humanoid = Instance.new("Humanoid")
humanoid.Parent = model

local shirt_clone = char["Shirt"]:Clone()
shirt_clone.Parent = model

part.Parent = model
part.CanCollide = true;

char.Torso["Right Shoulder"]:Destroy(); 
1 Like

I was going to say that the player’s body parts don’t have the CanCollide activated

well since its not parented to the character, i am able to enable can collide without it automatically turning can collide off

1 Like

image

image

function SetFire(part,duration)
	local fire = Instance.new("Fire")
	if part then 
		fire.Parent = part
		game.Debris:AddItem(fire,duration)
	end
end

script.Parent.Touched:Connect(function(part)
	local player = game.Players:GetPlayerFromCharacter(part.Parent)
	if player and player.Character then
		local character = player.Character
		if not character:GetAttribute("LostLeftArm") then
			character:SetAttribute("LostLeftArm",true)
			local leftUpperArm = character:FindFirstChild("LeftUpperArm")
			local leftLowerArm = character:FindFirstChild("LeftLowerArm")
			local leftHand = character:FindFirstChild("LeftHand")
			local shoulder = nil
			if leftUpperArm then
				SetFire(leftUpperArm,3)
				leftUpperArm:SetAttribute("CustomCollision",true)
				leftUpperArm.Name = "Dead_"..leftUpperArm.Name
				shoulder = leftUpperArm:FindFirstChild("LeftShoulder")
			end
			if leftLowerArm then
				SetFire(leftLowerArm,3)
				leftUpperArm.Name = "Dead_"..leftLowerArm.Name
				leftLowerArm:SetAttribute("CustomCollision",true)
			end
			if leftHand then
				SetFire(leftHand,3)
				leftUpperArm.Name = "Dead_"..leftHand.Name
				leftHand:SetAttribute("CustomCollision",true)
			end
			if shoulder then
				wait(2)
				shoulder:Destroy()
			end
		end
	end	
end)

image

local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")

humanoid.Died:Connect(function()
	if connection then
		connection:Disconnect()
	end
	connection = nil
end)

connection = game:GetService('RunService').Stepped:Connect(function()
	for _,part in pairs(character:GetChildren()) do
		if part:IsA("BasePart") then
			local attribute = part:GetAttribute("CustomCollision")
			if attribute ~= nil then
				part.CanCollide = attribute
			end
		end
	end
end)

I think it would be easier just to destroy the joint/attachment and then parent it outside of the player character. For cleanup, you can track all removed limbs and destroy them after a character destroying event. Then clear the array for garbage collection, of course.

2 Likes

your solution kinda looks confusing, is there an easier way to do it?

Yes, but it’s the most futureproof.

In my solution, though its a bit complicated, it has 2 benefits.

  1. The CustomCollision script can be used in any situation where you need to override the default Roblox collisions on a Character. Its a very stand alone script. All you need to do is SetAttribute(“CustomCollision”,), on a Characters body part, with a value of true or false to force true or false collision on that part.
    Parts that do not have the “CustomCollision” attribute, will just use Roblox default collision or the last collision that was set on them (If Roblox doesn’t force it for that part)

  2. By just removing the joint, and keeping the part parented to the Character, this allows for body colors and clothing, and scale to still apply to the part.
    Even animations, had I not renamed the parts, adding “Dead_” to the name, the arm on the ground would still be wiggling when I walk.

And yes, I went a ‘bit’ overboard, by adding a fire effect, and waiting 2 seconds before the arm falls off, but underneath the showmanship, its really very simple.

When you want a limb to fall off, you simply do this…

  1. SetAttribute("CustomCollision,true) – so it doesnt fall through the ground
  2. Rename the part, so the animations stop playing on them
  3. delete the Motor6D

and thats it

I got a few questions, why is there a run service event for the collision script, couldn’t you just turn on or turn off the collision with just a single line?
not only that but the remove arm script looks un necessary complicated with so much clutter, is there a way to reduce the amount of code but still work the same?

The run service is used because Roblox will constantly force set collision on body parts. The CusomCollision script really just allows us to overwrite the forced collision state on body parts.

In relation to this post, about detaching a limb, you can really just put this CustomCollision script in the starter characters and forget about it. Other than overriding the forced Roblox collision, it does nothing else.

As for the over complicated script for dropping an arm, thats my bad, ill post some super simple code in a few minutes.

function DropLeftArm(character)
	--Find Parts
	local leftUpperArm = character:FindFirstChild("LeftUpperArm")
	local leftLowerArm = character:FindFirstChild("LeftLowerArm")
	local leftHand = character:FindFirstChild("LeftHand")

	--make sure we have found all of these parts before we continue
	if leftUpperArm and leftLowerArm and leftHand then
		--look for our motor6d
		local leftShoulder = leftUpperArm:FindFirstChild("LeftShoulder")
		--make sure we found the shoulder before we continue
		if leftShoulder then
			--let all collisions to true for the arm parts
			leftUpperArm:SetAttribute("CustomCollision",true) --this causes the CustomCollision Script in the client to force this to true
			leftLowerArm:SetAttribute("CustomCollision",true)
			leftHand:SetAttribute("CustomCollision",true)
			--now optionally we rename the parts to stop animations from playing on them
			leftUpperArm.Name = leftUpperArm.Name .. "_Dead"
			leftLowerArm.Name = leftLowerArm.Name .. "_Dead"
			leftHand.Name = leftHand.Name .. "_Dead"
			--now we destroy the motor6d so the arm can fall
			leftShoulder:Destroy()
		end
	end	
end

No, it only sets collisions on state change. It’s not possible to override collisions without this enabled:

This lil script might can help you or give you some context:

-- Define the player
local player = game:GetService("Players").LocalPlayer

-- Define the limb parts
local leftArm = player.Character.LeftArm
local rightArm = player.Character.RightArm
local leftLeg = player.Character.LeftLeg
local rightLeg = player.Character.RightLeg

-- Define the joints
local leftArmJoint = leftArm:FindFirstChildOfClass("Motor6D")
local rightArmJoint = rightArm:FindFirstChildOfClass("Motor6D")
local leftLegJoint = leftLeg:FindFirstChildOfClass("Motor6D")
local rightLegJoint = rightLeg:FindFirstChildOfClass("Motor6D")

-- Remove the joints to detach the limbs
leftArmJoint:Destroy()
rightArmJoint:Destroy()
leftLegJoint:Destroy()
rightLegJoint:Destroy()

-- Parent the limbs to the workspace
leftArm.Parent = workspace
rightArm.Parent = workspace
leftLeg.Parent = workspace
rightLeg.Parent = workspace

-- Adjust the position and rotation of the limbs
leftArm.CFrame = leftArm.CFrame * CFrame.new(0, -1, 0)
rightArm.CFrame = rightArm.CFrame * CFrame.new(0, -1, 0)
leftLeg.CFrame = leftLeg.CFrame * CFrame.new(0, -1, 0)
rightLeg.CFrame = rightLeg.CFrame * CFrame.new(0, -1, 0)

yeah but i’ve found this post that proposes the idea not using your solution you’ve made for the collision script

Thanks for linking my post, there’s a behavior in roblox that makes limbs revert their collision states every frame

You can disable this (somewhat) by changing Workspace.HumanoidOnlySetCollisionsOnStateChange

https://create.roblox.com/docs/reference/engine/classes/Workspace#HumanoidOnlySetCollisionsOnStateChange

If you change the property to Enabled, then it’ll let you change collision on the parts without any spaghetti.

1 Like

I am aware of the collision only being set on state change, the code I provided, was created before this change, however it still works.
Whether you set it each frame or you set it after a state change, it still works to keep the humanoid from modifying the collisions.

Interesting. The last time I tried that it didn’t work for some reason. It might’ve been because I was using RenderStepped instead of Stepped.

1 Like

Hey @IceCreamPickels, might be a bit late, but you can do thise to fix the issue.

local function RemoveLimb(Hit)
	local HitPlayer = Hit.Parent
	local Torso = HitPlayer.Torso
	
	local Motors = {}
	
	--Appending all the motors inside a player
	for _, Motor: Instance in ipairs(Torso:GetChildren()) do
		if Motor:IsA("Motor6D") then
			table.insert(Motors, Motor)
		end
	end
	
	--Checks if their are still more motors left in the player to remove
	if Motors then
		local Humanoid = Hit.Parent:WaitForChild("Humanoid")
		if Humanoid.Health < Humanoid.MaxHealth / 2 then
			local Motor = Motors[math.random(1, #Motors)]
			table.remove(Motors, table.find(Motors, Motor))

			if Motor.Name == "Left Shoulder" then
				HitPlayer["Left Arm"].CanCollide = true
				Motor:Destroy()
			end

			if Motor.Name == "Right Hip" then
				HitPlayer["Right Leg"].CanCollide = true
				Motor:Destroy()
			end
		end
	end
end

The reason why your limbs are falling into the void is because there is no collision on body parts by default.

Hoping this solution helps you and anyone who still has this problem

2 Likes