Welding parts to player causing character to move a certain distance

  1. What do you want to achieve? I want my armor system NOT to teleport the player a certain amount of studs after armor is welded onto the character.

  2. What is the issue? The issue as stated above is when a player equips their armor, they move a certain distance in a certain direction. I believe this is caused by the action of the armor parts being welded to the player parts. I am using welds and not weld constraints, as I have had issues with weld constraints for this situation.

Here is the script:

game.Players.PlayerAdded:Connect(function(player)
	print("onplayerarmorjoin")
	    if player:WaitForChild("EquippedSaves"):FindFirstChild(script.Parent.Name).Value == true then
		if not player.Character:FindFirstChild(script.Parent.Name) then

			print("characterrespawn2")
			onPlayerRespawned(player)
		end
	end
end)


function onPlayerRespawned(newPlayer)
	for i,v in pairs(newPlayer.Character:GetChildren()) do
		if v:IsA("Model") then
			if string.find(v.Name,"Armor") then
				v:Destroy()
				newPlayer.EquippedSaves:FindFirstChild(v.Name).Value = false
			end
		end
	end
	local armor = newPlayer.Backpack.Tools:WaitForChild(script.Parent.Name):Clone()
	local armorscript = newPlayer.Backpack:FindFirstChild(script.Parent.Name)
	armor.Parent = newPlayer.Character
	newPlayer.Backpack:FindFirstChild(script.Parent.Name):WaitForChild("Equipped").Value = true
	newPlayer.Character.Humanoid.MaxHealth = newPlayer.Character.Humanoid.MaxHealth + armorscript.Stamina.Value
	newPlayer.Character.Humanoid.Health = newPlayer.Character.Humanoid.MaxHealth
	newPlayer.EquippedSaves:WaitForChild(script.Parent.Name).Value = true
	for index, armorParts in pairs(armor:GetChildren()) do
		for index, playerParts in pairs(newPlayer.Character:GetChildren()) do
			if playerParts:IsA("BasePart") then
				if armorParts.Name ~= "Physical" or "Price" or "Stamina" or "Type" or "Wizardry" or "Equipped" or "Script" then
					if armorParts.Name == playerParts.Name then




						armorParts.PrimaryPart.CFrame = playerParts.CFrame
						local weld = Instance.new("WeldConstraint")
						weld.Part0 = armorParts.PrimaryPart
						weld.Part1 = playerParts
						weld.Parent = armorParts.PrimaryPart






						if armorParts.Name and playerParts.Name == "LeftUpperArm" then
							armorParts.PrimaryPart.CFrame = playerParts.CFrame * CFrame.new(0,0.7,0)
							local armorindivid = armor:WaitForChild("LeftUpperArm"):GetChildren()

							local weld = Instance.new("Weld")
							weld.Part0 = playerParts
							weld.Part1 = armorParts.PrimaryPart
							weld.Parent = armorParts.PrimaryPart
							weld.C0 = CFrame.new(0,0.6,0)
						end

						if armorParts.Name and playerParts.Name == "RightUpperArm" then
							local orientation = nil
							armorParts.PrimaryPart.CFrame = playerParts.CFrame * CFrame.new(0,0.7,0)
							local armorindivid = armor:WaitForChild("RightUpperArm"):GetChildren()
							local weld = Instance.new("Weld")
							weld.Part0 = playerParts
							weld.Part1 = armorParts.PrimaryPart
							weld.Parent = armorParts.PrimaryPart
							weld.C0 = CFrame.new(0,0.6,0)


						end
					elseif armorParts.Name == "FaceShield" then
						print("faceshield")

						armorParts.PrimaryPart.CFrame = newPlayer.Character.Head.CFrame * CFrame.new(0,0,-0.5)
						local weld = Instance.new("Weld")
						weld.Part0 = newPlayer.Character:WaitForChild("Head")
						weld.Part1 = armorParts.PrimaryPart
						weld.Parent = armorParts.PrimaryPart
						armorParts.PrimaryPart.CFrame = newPlayer.Character.Head.CFrame * CFrame.new(0,0,-0.5)
						--	armorParts.PrimaryPart.Orientation = Vector3.new(0,180,0)
						weld.C0 = CFrame.new(0,0,-0.5)
					end
				end
			end
		end
	end
end

function OnPlayerUnequip(player)
	local armorscript = player.Backpack:FindFirstChild(script.Parent.Name)
	local armor = player.Backpack.Tools:WaitForChild(script.Parent.Name)
	player.Backpack:FindFirstChild(script.Parent.Name):WaitForChild("Equipped").Value = false
	player.Character:WaitForChild(script.Parent.Name):Destroy()	
	player.Character.Humanoid.MaxHealth = player.Character.Humanoid.MaxHealth - armorscript.Stamina.Value
	player.Character.Humanoid.Health = player.Character.Humanoid.MaxHealth
	player.EquippedSaves:WaitForChild(script.Parent.Name).Value = false

end


local function playerAdded(player)
	wait(5)
	print("playeradded")
	if player.EquippedSaves:FindFirstChild(script.Parent.Name).Value == true then
		if not player.Character:FindFirstChild(script.Parent.Name) then


			onPlayerRespawned(player)
		end
	end
end


for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
	if player.Character then
		playerAdded(player)
	else
		player.CharacterAdded:Wait()
		playerAdded(player)
	end
end	


script.Parent.ArmorServer.OnServerEvent:Connect(function(player,action)

	--	if player:WaitForChild("EquippedSaves"):FindFirstChild(script.Parent.Name).Value == true then

	for i,v in pairs(player.Character:GetChildren()) do
		if v:IsA("Model") then
			if string.find(v.Name,"Armor") then
				OnPlayerUnequip(player)
			else
				onPlayerRespawned(player)
			end
		end
	end

end)

Here is a video of the issue:Video

  1. What solutions have you tried so far? I have anchored the humanoidrootpart before welding and unanchored after welding, but it still teleports the player.

Thanks for helping - CyberWizard

Try to put the parts of the armor without collision

for index, armorParts in pairs(armor:GetChildren()) do
	armorParts.CanCollide = false
	...
end

The parts are non collidable by default.

Try to put Parent to Workspace:

armor.Parent = game.Workspace

It is being parented to workspace. It is inside the player’s character.

By resizing the player model by adding parts, it can cause the effect you mention.

As they are welded it does not matter where you place them

I do not understand what you mean when you say resizing the player model. I am just adding a model inside the player model. If I am resizing the player by adding the armor, what would be the solution?

The armor parts aren’t anchored by default right?

All armor parts are not anchored. If they were, I would not be able to move.

It’s possible because you’re changing the weld CFrames after the armor has already been welded to the character.

1 Like

That solved 75% of the issue. Now the player is not teleporting around the map, but the player is still teleporting up when armor is equipped.

New script:

game.Players.PlayerAdded:Connect(function(player)
	print("onplayerarmorjoin")
	if player:WaitForChild("EquippedSaves"):FindFirstChild(script.Parent.Name).Value == true then
		if not player.Character:FindFirstChild(script.Parent.Name) then

			print("characterrespawn2")
			onPlayerRespawned(player)
		end
	end
end)


function onPlayerRespawned(newPlayer)
	for i,v in pairs(newPlayer.Character:GetChildren()) do
		if v:IsA("Model") then
			if string.find(v.Name,"Armor") then
				v:Destroy()
				newPlayer.EquippedSaves:FindFirstChild(v.Name).Value = false
			end
		end
	end
	local armor = newPlayer.Backpack.Tools:WaitForChild(script.Parent.Name):Clone()
	local armorscript = newPlayer.Backpack:FindFirstChild(script.Parent.Name)
	armor.Parent = newPlayer.Character
	newPlayer.Backpack:FindFirstChild(script.Parent.Name):WaitForChild("Equipped").Value = true
	newPlayer.Character.Humanoid.MaxHealth = newPlayer.Character.Humanoid.MaxHealth + armorscript.Stamina.Value
	newPlayer.Character.Humanoid.Health = newPlayer.Character.Humanoid.MaxHealth
	newPlayer.EquippedSaves:WaitForChild(script.Parent.Name).Value = true
	for index, armorParts in pairs(armor:GetChildren()) do
		for index, playerParts in pairs(newPlayer.Character:GetChildren()) do
			if playerParts:IsA("BasePart") then
				if armorParts.Name ~= "Physical" or "Price" or "Stamina" or "Type" or "Wizardry" or "Equipped" or "Script" then
					if armorParts.Name == playerParts.Name then




						armorParts.PrimaryPart.CFrame = playerParts.CFrame
						local weld = Instance.new("WeldConstraint")
						weld.Part0 = armorParts.PrimaryPart
						weld.Part1 = playerParts
						weld.Parent = armorParts.PrimaryPart






						if armorParts.Name and playerParts.Name == "LeftUpperArm" then
							armorParts.PrimaryPart.CFrame = playerParts.CFrame * CFrame.new(0,0.7,0)
							local armorindivid = armor:WaitForChild("LeftUpperArm"):GetChildren()

							local weld = Instance.new("Weld")
							weld.C0 = CFrame.new(0,0.6,0)
							weld.Part0 = playerParts
							weld.Part1 = armorParts.PrimaryPart
							weld.Parent = armorParts.PrimaryPart
						
						end

						if armorParts.Name and playerParts.Name == "RightUpperArm" then
							local orientation = nil
							armorParts.PrimaryPart.CFrame = playerParts.CFrame * CFrame.new(0,0.7,0)
							local armorindivid = armor:WaitForChild("RightUpperArm"):GetChildren()
							local weld = Instance.new("Weld")
							weld.C0 = CFrame.new(0,0.6,0)
							weld.Part0 = playerParts
							weld.Part1 = armorParts.PrimaryPart
							weld.Parent = armorParts.PrimaryPart
						


						end
					elseif armorParts.Name == "FaceShield" then
						print("faceshield")

						armorParts.PrimaryPart.CFrame = newPlayer.Character.Head.CFrame * CFrame.new(0,0,-0.5)
						local weld = Instance.new("Weld")
						weld.C0 = CFrame.new(0,0,-0.5)
						armorParts.PrimaryPart.CFrame = newPlayer.Character.Head.CFrame * CFrame.new(0,0,-0.5)
						weld.Part0 = newPlayer.Character:WaitForChild("Head")
						weld.Part1 = armorParts.PrimaryPart
						weld.Parent = armorParts.PrimaryPart
						
						--armorParts.PrimaryPart.Orientation = Vector3.new(0,180,0)
						
					end
				end
			end
		end
	end
end

function OnPlayerUnequip(player)
	local armorscript = player.Backpack:FindFirstChild(script.Parent.Name)
	local armor = player.Backpack.Tools:WaitForChild(script.Parent.Name)
	player.Backpack:FindFirstChild(script.Parent.Name):WaitForChild("Equipped").Value = false
	player.Character:WaitForChild(script.Parent.Name):Destroy()	
	player.Character.Humanoid.MaxHealth = player.Character.Humanoid.MaxHealth - armorscript.Stamina.Value
	player.Character.Humanoid.Health = player.Character.Humanoid.MaxHealth
	player.EquippedSaves:WaitForChild(script.Parent.Name).Value = false

end


local function playerAdded(player)
	wait(5)
	print("playeradded")
	if player.EquippedSaves:FindFirstChild(script.Parent.Name).Value == true then
		if not player.Character:FindFirstChild(script.Parent.Name) then


			onPlayerRespawned(player)
		end
	end
end


for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
	if player.Character then
		playerAdded(player)
	else
		player.CharacterAdded:Wait()
		playerAdded(player)
	end
end	


script.Parent.ArmorServer.OnServerEvent:Connect(function(player,action)

	--	if player:WaitForChild("EquippedSaves"):FindFirstChild(script.Parent.Name).Value == true then

	for i,v in pairs(player.Character:GetChildren()) do
		if v:IsA("Model") then
			if string.find(v.Name,"Armor") then
				OnPlayerUnequip(player)
			else
				onPlayerRespawned(player)
			end
		end
	end

end)

new video:2022-07-13 13-29-03 GIF | Gfycat

Thanks for the help :smile: - CyberWizard

1 Like

I want to say that this thread is not solved completely yet. 75% solved. Refer back to my previous message in thread for the rest of the issue.

Set anchored to true at the beginning of the script and false at the end for HumanoidRootPart

function onPlayerRespawned(newPlayer)
    newPlayer.Character.HumanoidRootPart.Anchored = true
    ...
    newPlayer.Character.HumanoidRootPart.Anchored = false
end

As said in the original post by me under the “what solutions have you tried so far?” section, I have already tried anchoring the humanoidrootpart, and it still does not work. I deleted it from the code included in the original post because it did not work. Sorry for any confusion.

Have you tried adding the armor to the worldspace?

game.Players.PlayerAdded:Connect(function(player)
	print("onplayerarmorjoin")
	if player:WaitForChild("EquippedSaves"):FindFirstChild(script.Parent.Name).Value == true then
		if not player.Character:FindFirstChild(script.Parent.Name) then

			print("characterrespawn2")
			onPlayerRespawned(player)
		end
	end
end)


function onPlayerRespawned(newPlayer)
	for i,v in pairs(newPlayer.Character:GetChildren()) do
		if v:IsA("Model") then
			if string.find(v.Name,"Armor") then
				v:Destroy()
				newPlayer.EquippedSaves:FindFirstChild(v.Name).Value = false
			end
		end
	end
	local armor = newPlayer.Backpack.Tools:WaitForChild(script.Parent.Name):Clone()
	local armorscript = newPlayer.Backpack:FindFirstChild(script.Parent.Name)
	armor.Parent = game.Workspace
	newPlayer.Backpack:FindFirstChild(script.Parent.Name):WaitForChild("Equipped").Value = true
	newPlayer.Character.Humanoid.MaxHealth = newPlayer.Character.Humanoid.MaxHealth + armorscript.Stamina.Value
	newPlayer.Character.Humanoid.Health = newPlayer.Character.Humanoid.MaxHealth
	newPlayer.EquippedSaves:WaitForChild(script.Parent.Name).Value = true
	for index, armorParts in pairs(armor:GetChildren()) do
		for index, playerParts in pairs(newPlayer.Character:GetChildren()) do
			if playerParts:IsA("BasePart") then
				if armorParts.Name ~= "Physical" or "Price" or "Stamina" or "Type" or "Wizardry" or "Equipped" or "Script" then
					if armorParts.Name == playerParts.Name then




						armorParts.PrimaryPart.CFrame = playerParts.CFrame
						local weld = Instance.new("WeldConstraint")
						weld.Part0 = armorParts.PrimaryPart
						weld.Part1 = playerParts
						weld.Parent = game.Workspace






						if armorParts.Name and playerParts.Name == "LeftUpperArm" then
							armorParts.PrimaryPart.CFrame = playerParts.CFrame * CFrame.new(0,0.7,0)
							local armorindivid = armor:WaitForChild("LeftUpperArm"):GetChildren()

							local weld = Instance.new("Weld")
							weld.C0 = CFrame.new(0,0.6,0)
							weld.Part0 = playerParts
							weld.Part1 = armorParts.PrimaryPart
							weld.Parent = game.Workspace
						
						end

						if armorParts.Name and playerParts.Name == "RightUpperArm" then
							local orientation = nil
							armorParts.PrimaryPart.CFrame = playerParts.CFrame * CFrame.new(0,0.7,0)
							local armorindivid = armor:WaitForChild("RightUpperArm"):GetChildren()
							local weld = Instance.new("Weld")
							weld.C0 = CFrame.new(0,0.6,0)
							weld.Part0 = playerParts
							weld.Part1 = armorParts.PrimaryPart
							weld.Parent = game.Workspace
						


						end
					elseif armorParts.Name == "FaceShield" then
						print("faceshield")

						armorParts.PrimaryPart.CFrame = newPlayer.Character.Head.CFrame * CFrame.new(0,0,-0.5)
						local weld = Instance.new("Weld")
						weld.C0 = CFrame.new(0,0,-0.5)
						armorParts.PrimaryPart.CFrame = newPlayer.Character.Head.CFrame * CFrame.new(0,0,-0.5)
						weld.Part0 = newPlayer.Character:WaitForChild("Head")
						weld.Part1 = armorParts.PrimaryPart
						weld.Parent = game.Workspace
						
						--armorParts.PrimaryPart.Orientation = Vector3.new(0,180,0)
						
					end
				end
			end
		end
	end
end

function OnPlayerUnequip(player)
	local armorscript = player.Backpack:FindFirstChild(script.Parent.Name)
	local armor = player.Backpack.Tools:WaitForChild(script.Parent.Name)
	player.Backpack:FindFirstChild(script.Parent.Name):WaitForChild("Equipped").Value = false
	player.Character:WaitForChild(script.Parent.Name):Destroy()	
	player.Character.Humanoid.MaxHealth = player.Character.Humanoid.MaxHealth - armorscript.Stamina.Value
	player.Character.Humanoid.Health = player.Character.Humanoid.MaxHealth
	player.EquippedSaves:WaitForChild(script.Parent.Name).Value = false

end


local function playerAdded(player)
	wait(5)
	print("playeradded")
	if player.EquippedSaves:FindFirstChild(script.Parent.Name).Value == true then
		if not player.Character:FindFirstChild(script.Parent.Name) then


			onPlayerRespawned(player)
		end
	end
end


for _, player in ipairs(game:GetService("Players"):GetPlayers()) do
	if player.Character then
		playerAdded(player)
	else
		player.CharacterAdded:Wait()
		playerAdded(player)
	end
end	


script.Parent.ArmorServer.OnServerEvent:Connect(function(player,action)

	--	if player:WaitForChild("EquippedSaves"):FindFirstChild(script.Parent.Name).Value == true then

	for i,v in pairs(player.Character:GetChildren()) do
		if v:IsA("Model") then
			if string.find(v.Name,"Armor") then
				OnPlayerUnequip(player)
			else
				onPlayerRespawned(player)
			end
		end
	end

end)

I change this:

...
armor.Parent = game.Workspace
...
weld.Parent = game.Workspace
...
weld.Parent = game.Workspace
...

Try please

I stated originally that the armor is a descendent of the workspace because it is in the character. I find it inconvenient to have all armor stored in the workspace for all characters. It should not matter because it is still descendent of the workspace.

I tried to make a simple code to add armor. But I can’t reproduce the error.

-- Script in ServerScriptService
local parts = {
	'Head', 'UpperTorso', 'LowerTorso', 
	'RightFoot', 'RightFoot', 'RightHand', 'RightLowerArm', 'RightLowerLeg', 'RightUpperLeg',
	'LeftFoot', 'LeftFoot', 'LeftHand', 'LeftLowerArm', 'LeftLowerLeg', 'LeftUpperLeg'
}


game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		wait(2)
		
		local objects = {}
		
		for _, p in ipairs(parts) do
			objects[#objects + 1] = character:WaitForChild(p)
		end
		
		while(true) do
			local armadura = {}
		
			for _, p in ipairs(objects) do
				local arm = Instance.new('Part')
				arm.Size = p.CFrame.LookVector.Unit * 0.1 + p.CFrame.UpVector.Unit * 0.8 + p.CFrame.RightVector.Unit 
				arm.Position = p.Position + p.CFrame.LookVector.Unit
				arm.Parent = character

				armadura[#armadura + 1] = arm
				
				local w = Instance.new('WeldConstraint')
				w.Part0 = arm
				w.Part1 = p
				w.Parent = character
				
				armadura[#armadura + 1] = w
			end

			wait(10)
			
			for _, p in ipairs(armadura) do
				p:Destroy()
			end
			
			wait(2)
		end
	end)
end)

I appreciate your efforts in trying to solve this. I will leave this discussion open until there is a full solution to my code.

I confess I didn’t read your whole script, but this might be a latency issue?

On the serverside, you are positioning the armor to where the server sees the player in the game. This might differ a few studs to where the local player actually sees themselves? Then again, this could just be an issue with the character teleporting to where the armor was “positioned”.

It’ll take some testing to confirm it, but an alternate solution is to make the armor Roblox Accessorys so roblox automatically welds them to the character (which should avoid the teleporting issue). All you would have to do is parent the accessory to the character and the game will do the welding.


https://developer.roblox.com/en-us/api-reference/class/Accessory

I had to manually set a different CFrame for the welding on each armor piece in my script. In an accessory, you said roblox takes care of the welding. I am not sure if this means I cannot manually override an offset CFrame for the welding. Also how would I go about converting the model in the picture below to an accessory?
Screenshot 2022-07-14 171330