Welded players act weirdly

Hi! So I have a piggyback system which auto-checks if someone died or not. This is the function:

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		char.Humanoid.Died:Connect(function()
			local plr1 = nil
			local plr2 = nil
			for i,v in runningPiggybacks do
				if i == plr then -- IF HOST == PLAYER WHO LEFT / REQUESTED LEAVE
					plr1 = plr
					plr2 = v
					break
				else
					if v == plr then -- IF SECOND PLAYER == PLAYER WHO LEFT / REQUESTED LEAVE
						plr1 = i
						plr2 = plr
						break
					end
				end
			end
			
			if plr1 and plr2 then
				PiggybackHandler.StopPiggyback(plr2,plr)
			end
		end)
	end)
end)

→

PiggybackHandler.StopPiggyback = function(plr,plrWho)
	local plr1 = nil
	local plr2 = nil
	for i,v in runningPiggybacks do
		if i == plr then -- IF HOST == PLAYER WHO LEFT / REQUESTED LEAVE
			plr1 = plr
			plr2 = v
			break
		else
			if v == plr then -- IF SECOND PLAYER == PLAYER WHO LEFT / REQUESTED LEAVE
				plr1 = i
				plr2 = plr
				break
			end
		end
	end
	if plr1 and plr2 then
		runningPiggybacks[plr1] = nil
		
		remotes.ToggleStop:FireClient(plr1,false)
		remotes.ToggleStop:FireClient(plr2,false)
		
		local playerWhoReset = plr2
		
		local notedPos = nil
		local PlrToChange = nil
		if plr1 == plrWho then
			PlrToChange = plr2
		elseif plr2 == plrWho then
			PlrToChange = plr1
		end
		notedPos = PlrToChange.Character.HumanoidRootPart.CFrame
		
		plr1:LoadCharacter()
		plr2:LoadCharacter()
		
		wait()
			
		PlrToChange.Character.HumanoidRootPart.CFrame = notedPos
		
		--[[if plr1.Character then
			AnimationsHandler.StopAnimation(plr1,"Plr1")
			if plr1.Character.HumanoidRootPart:FindFirstChild("PiggybackWeld") then
				plr1.Character.HumanoidRootPart.PiggybackWeld.Part0 = nil
				plr1.Character.HumanoidRootPart.PiggybackWeld.Part1 = nil
				plr1.Character.HumanoidRootPart.PiggybackWeld:Destroy()
			end
		end
		if plr2.Character then
			AnimationsHandler.StopAnimation(plr2,"Plr2")
			plr2.Character.Humanoid.WalkSpeed = MiscModule.Walkspeed
			plr2.Character.Humanoid.AutoRotate = true
			plr2.Character.Humanoid.PlatformStand = false
			
			if plr2.Character.HumanoidRootPart:FindFirstChild("PiggybackWeld") then
				plr2.Character.HumanoidRootPart.PiggybackWeld.Part0 = nil
				plr2.Character.HumanoidRootPart.PiggybackWeld.Part1 = nil
				plr2.Character.HumanoidRootPart.PiggybackWeld.Enabled = true
				plr2.Character.HumanoidRootPart.PiggybackWeld:Destroy()
			end
			
			for i,v in plr2.Character:GetChildren() do
				if v:IsA("BasePart") then
					print("TURNED MASSLESS TO FALSE")
					v.Massless = false
				end
			end
		end--]]
	end
end

And this way it is working now but when I manually remove the weld’s I have put on the player who is being carried, SOMETIMES incase a person resets, the other person is being “resetted” too. But the weird thing is: It is only then for the player who resetted themself. However, this whole script is server sided. Could this be the cause of the welds? Please help. :sob:

This is the code for the welding:

PiggybackHandler.Piggyback = function(plr1,plr2)
	runningPiggybacks[plr1] = plr2
	local plr1Char = plr1.Character
	local plr2Char = plr2.Character
	
	plr2Char.Humanoid.WalkSpeed = 0
	plr2Char.Humanoid.AutoRotate = false
	plr2Char.Humanoid.PlatformStand = true
	
	for i,v in plr2Char:GetChildren() do
		if v:IsA("BasePart") then
			v.Massless = true
		end
	end
	
	local newWeld = Instance.new("Weld")
	newWeld.Name = "PiggybackWeld"
	newWeld.Parent = plr2Char.HumanoidRootPart
	newWeld.Part0 = plr1Char.HumanoidRootPart
	newWeld.Part1 = plr2Char.HumanoidRootPart
	
	AnimationsHandler.PlayAnimation(plr1,"Plr1")
	AnimationsHandler.PlayAnimation(plr2,"Plr2")
	
	remotes.ToggleStop:FireClient(plr1,true)
	remotes.ToggleStop:FireClient(plr2,true)
end

I’ve been battling this issue for years.
If the weld is parented under the character model and the Part1 or Part0 is joint broken either from death or weld removal, it will also apply to the other character. It’s a very specific and inconsistent interaction but it’s part of the old way Roblox was coded.

If you parent the weld outside of the character model, like a folder in workspace, it should fix the issue :slight_smile: .

newWeld.Parent = workspace.PiggybackWeldStorage
2 Likes

THANK YOU SO MUCH! I really wasn’t aware of this and I will make sure to test it out tomorrow. I really couldn’t even think of that. :sob:

Hey! This sadly did not fix the issue:


I would appreciate it by a lot if you could have a look again. :pray: :sob:

This is the edited code:

PiggybackHandler.Piggyback = function(plr1,plr2)
	runningPiggybacks[plr1] = plr2
	local plr1Char = plr1.Character
	local plr2Char = plr2.Character
	
	plr2Char.Humanoid.WalkSpeed = 0
	plr2Char.Humanoid.AutoRotate = false
	plr2Char.Humanoid.PlatformStand = true
	
	for i,v in plr2Char:GetChildren() do
		if v:IsA("BasePart") then
			v.Massless = true
		end
	end
	
	local newWeld = Instance.new("Weld")
	newWeld.Name = plr1.Name
	newWeld.Parent = game.Workspace.PiggybackWelds
	newWeld.Part0 = plr1Char.HumanoidRootPart
	newWeld.Part1 = plr2Char.HumanoidRootPart
	
	AnimationsHandler.PlayAnimation(plr1,"Plr1")
	AnimationsHandler.PlayAnimation(plr2,"Plr2")
	
	remotes.ToggleStop:FireClient(plr1,true)
	remotes.ToggleStop:FireClient(plr2,true)
end
PiggybackHandler.StopPiggyback = function(plr,plrWho)
	local plr1 = nil
	local plr2 = nil
	for i,v in runningPiggybacks do
		if i == plr then -- IF HOST == PLAYER WHO LEFT / REQUESTED LEAVE
			plr1 = plr
			plr2 = v
			break
		else
			if v == plr then -- IF SECOND PLAYER == PLAYER WHO LEFT / REQUESTED LEAVE
				plr1 = i
				plr2 = plr
				break
			end
		end
	end
	if plr1 and plr2 then
		runningPiggybacks[plr1] = nil
		
		remotes.ToggleStop:FireClient(plr1,false)
		remotes.ToggleStop:FireClient(plr2,false)
		
		local playerWhoReset = plr2
		
		local notedPos = nil
		local PlrToChange = nil
		if plr1 == plrWho then
			PlrToChange = plr2
		elseif plr2 == plrWho then
			PlrToChange = plr1
		end
		notedPos = PlrToChange.Character.HumanoidRootPart.CFrame
		
		--plr1:LoadCharacter()
		--plr2:LoadCharacter()
		
		if plr1.Character then
			AnimationsHandler.StopAnimation(plr1,"Plr1")
			if game.Workspace.PiggybackWelds:FindFirstChild(plr1.Name) then
				game.Workspace.PiggybackWelds[plr1.Name].Part0 = nil
				game.Workspace.PiggybackWelds[plr1.Name].Part1 = nil
				game.Workspace.PiggybackWelds[plr1.Name]:Destroy()
			end
		end
		if plr2.Character then
			AnimationsHandler.StopAnimation(plr2,"Plr2")
			plr2.Character.Humanoid.WalkSpeed = MiscModule.Walkspeed
			plr2.Character.Humanoid.AutoRotate = true
			plr2.Character.Humanoid.PlatformStand = false

			for i,v in plr2.Character:GetChildren() do
				if v:IsA("BasePart") then
					v.Massless = false
				end
			end
		end
		
		wait()
			
		PlrToChange.Character.HumanoidRootPart.CFrame = notedPos
	end
end

Turn off “BreakJointsOnDeath” under the Humanoid Property, it should fix it.

https://gyazo.com/2a0aada9725d4972c303151e5339cf90

Then this happens.

The reason why both player dies when one resets is because they are welded together, and since BreakJointsOnDeath is On by Default… when one die, it’ll break every joints that’s connected to it… Including the neck on the Other Player. And also because of when the Neck joint is Destroyed, the Player Will Die. In short it’s basically a chain effect caused by BreakJointsOnDeath.

Now, the only way you can fix it is probably to disable BreakJointsOnDeath and Using a Script, destroy the Weld connecting Both Players. Then destroying all Joints on the Player that died. To replicate Roblox lego pieces breaking thing idk death effect

Well but I had BreakJoints on false and then the stuff in the Gyazo happens. The removement of the welds won’t work but in the deletion script, it does remove them…

It should work. I use the same code pattern for my game.

Try doing both things first:

  • use WeldConstraint instead of Weld
  • disable Humanoid.BreakJointsOnDeath permanently (set it off on character spawning)

Hi, thank you for your reply! I will try it out tomorrow! :slight_smile:

1 Like

You may want to use a AlignPosition and AlignOrientation instead (made on the client-side for both clients) since welds can act pretty wacky.