Character gets randomly teleported to npcs

Hi devs, for some reason, my character gets teleported to NPCs which are supposed to recreate my character (accessories get cloned etc).

I use this StarterCharacter by default.

I have 4 npcs like this in my game: They are supposed to look like the character (default starter character or if a custom one is saved, this one)

Here’s the code inside these NPCs:

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		wait(10)
		for i, v in pairs(char:GetChildren()) do
			if v:IsA("Shirt") then
				local shirt = Instance.new("Shirt")
				shirt.ShirtTemplate = v.ShirtTemplate
				shirt.Name = "Shirt"
				shirt.Parent = script.Parent
			elseif v:IsA("Pants") then
				local pants = Instance.new("Pants")
				pants.PantsTemplate = v.PantsTemplate
				pants.Name = "Pants"
				pants.Parent = script.Parent
			end
			if v:IsA("Accessory") then
				v:Clone().Parent = script.Parent
			elseif v.Name == "Torso" or v.Name == "Head" or v.Name == "Left Arm" or v.Name == "Right Arm" or v.Name == "Left Leg" or v.Name == "Right Leg" then
				script.Parent:FindFirstChild(v.Name).Color = v.Color
				if v.Name == "Head" then
					script.Parent.Head.Face.Texture = v:FindFirstChild("Face").Texture
				end
			end
		end
	end)
end)

Mostly this works fine. However, sometimes (quite rare maybe every 10th time) the player’s character gets teleported to one of these NPCs. This happens, after the Script inside the npcs waited for 10 seconds and the clone code gets fired. So far this only happened when I had saved custom accessories, shirts etc)

Here’s the code that saves the custom accessories, shirts, faces, skin colors and pants.

local DataStoreService = game:GetService("DataStoreService")
local saveEvent = game:GetService("ReplicatedStorage").Remotes.AvatarCustomization.SaveEvent
local SaveData = DataStoreService:GetDataStore("SaveAvatar")
local insertservice = game:GetService("InsertService")

local function onPlayerJoin(char)
	wait(1)
	local playerUserId = "Char_"..game.Players:GetPlayerFromCharacter(char).UserId
	local data 
	
	local success, errormessage = pcall(function()
		data = SaveData:GetAsync(playerUserId)
	end)
	
	if success then
		if data then
			char:FindFirstChild("RobloxVisor2019"):Destroy()
			--SKIN TONE
			for i, v in pairs(char:GetChildren()) do
				if v.Name == "Torso" or v.Name == "Head" or v.Name == "Left Arm" or v.Name == "Right Arm" or v.Name == "Left Leg" or v.Name == "Right Leg" then
					v.Color = Color3.fromRGB(data[v.Name.."R"], data[v.Name.."G"], data[v.Name.."B"])
				end
			end
			
			--FACE
			char:FindFirstChild("Head").Face.Texture = data["Face"]
			
			--ACCESSORY PASS
			
			local tab = {
				1,
				2,
				3,
				4,
				5,
				6,
				7,
				8,
				9,
				10,
				11,
				12,
				13,
				14,
				15,
				16
			}
			
			for i, v in pairs(tab) do
				if data["Accessory"..i] then
					local success, err = pcall(function()
						local assetModel = insertservice:LoadAsset(tonumber(data["Accessory"..i]))
						assetModel.Parent = game.Workspace
						local asset = assetModel:GetChildren()[1]
						if asset:IsA("Accessory") then
							char.Humanoid:AddAccessory(asset)
							local idvalue = Instance.new("NumberValue")
							idvalue.Name = "IdValue"
							idvalue.Parent = asset
							idvalue.Value = data["Accessory"..i]

						elseif asset:IsA("Shirt") then
							if char:FindFirstChildWhichIsA("Shirt") then
								char:FindFirstChildWhichIsA("Shirt"):Destroy()
							end
							asset.Parent = char
						elseif asset:IsA("Pants") then
							if char:FindFirstChildWhichIsA("Pants") then
								char:FindFirstChildWhichIsA("Pants"):Destroy()
							end
							asset.Parent = char
						end
						assetModel:Destroy()
					end)
				end
			end
			
			
			--REPLICATED ACCESSORIES
			for i, v in pairs(tab) do
				if data["ReplicatedAccessory"..i] then
					if game:GetService("ReplicatedStorage").CustomAccessories:FindFirstChild(data["ReplicatedAccessory"..i]) ~= nil then
						game:GetService("ReplicatedStorage").CustomAccessories:FindFirstChild(data["ReplicatedAccessory"..i]):Clone().Parent = char
					elseif game:GetService("ReplicatedStorage").CustomAccessories.Hair:FindFirstChild(data["ReplicatedAccessory"..i]) ~= nil then
						game:GetService("ReplicatedStorage").CustomAccessories.Hair:FindFirstChild(data["ReplicatedAccessory"..i]):Clone().Parent = char
					end
				end
			end
			
			--SHIRTS
			if data["Shirt"] then
				local shirt = Instance.new("Shirt")
				shirt.Name = "Shirt"
				shirt.ShirtTemplate = data["Shirt"]
				shirt.Parent = char
			end
			
			--PANTS
			if data["Pants"] then
				local pants = Instance.new("Pants")
				pants.Name = "Pants"
				pants.PantsTemplate = data["Pants"]
				pants.Parent = char
			end
		end
	else
		for i, v in pairs(char:GetChildren()) do
			if v.Name == "Torso" then
				v.Color = Color3.fromRGB(196, 40, 28)
			elseif v.Name == "Head" or v.Name == "Left Arm" or v.Name == "Right Arm" then
				v.Color = Color3.fromRGB(253, 234, 141)
			elseif v.Name == "Left Leg" or v.Name == "Right Leg" then
				v.Color = Color3.fromRGB(110, 153, 202)
			end
		end
		--
	end
	
end

local function create_table(plr)
	local char_stats = {}
	--SKIN TONE
	for _, stat in pairs(plr.Character:GetChildren()) do
		if stat.Name == "Torso" or stat.Name == "Head" or stat.Name == "Left Arm" or stat.Name == "Right Arm" or stat.Name == "Left Leg" or stat.Name == "Right Leg" then
			char_stats[stat.Name.."R"] = stat.Color.R * 255
			char_stats[stat.Name.."G"] = stat.Color.G * 255
			char_stats[stat.Name.."B"] = stat.Color.B * 255
		end
		
		----FACE
		char_stats["Face"] = plr.Character:FindFirstChild("Head").Face.Texture
		
		--ACCESSORIES PASS
		local number = 0
		for i, v in pairs(plr.Character:GetChildren()) do
			if v:IsA("Accessory") then
				if v:FindFirstChild("IdValue") then
					number = number + 1
					if number < 16 then
						char_stats["Accessory"..number] = v:FindFirstChild("IdValue").Value
					end
				else
					--custom accessory
					number = number + 1
					if number < 16 then
						char_stats["ReplicatedAccessory"..number] = v.Name
					end
				end
			end
		end
		
		
		--SHIRTS
		if stat:IsA("Shirt") then
			char_stats["Shirt"] = stat.ShirtTemplate
		elseif stat:IsA("Pants") then
			char_stats["Pants"] = stat.PantsTemplate		
		end
	end
	return char_stats
end

local function onPlayerRemoving(plr)
	local char_stats = create_table(plr)
	local success, err = pcall(function()
		local playerUserId = "Char_"..plr.UserId
		SaveData:SetAsync(playerUserId,char_stats)
	end)
	if not success then
		warn(err)
	end
end

saveEvent.OnServerEvent:Connect(function(plr)
	for i, plr in pairs(game.Players:GetPlayers()) do
		local char_stats = create_table(plr)
		local success, err = pcall(function()
			local playerUserId = "Char_"..plr.UserId
			SaveData:SetAsync(playerUserId,char_stats)
			print("character saved")
		end)
		if not success then
			warn(err)
		end
	end
end)

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		onPlayerJoin(char)
	end)
end)
	
while wait(60) do
	for i, plr in pairs(game.Players:GetPlayers()) do
		local char_stats = create_table(plr)
		local success, err = pcall(function()
			local playerUserId = "Char_"..plr.UserId
			SaveData:SetAsync(playerUserId,char_stats)
		end)
		if not success then
			warn(err)
		end
	end
end

sorry this is really long. I don’t know how much of this information you need. Thank you for reading!

Could it be because when you clone the hats that the weld holding the hat to the player is still set to the player and not the NPC?

1 Like

Nvm, I tried it and it worked. Thank you!