Im using a Character shop from a tutorial made in 2020, Character Shop Tutorial (Part 4 Final) | Roblox Studio - YouTube (Link to it if need to see it), the problem is that when players load into the game, there is a chance of them spawning a clone of themselves
Proof: https://gyazo.com/3a7cd33ca615470574436b3858b8daf0
I have no clue what the cause of it, im assuming it is something with this script since this is what loads and updates the Characters:
local StarterCharScripts = game.StarterPlayer.StarterCharacterScripts
local ChangeCamSubject = game.ReplicatedStorage.Remotes.ChangeCamSubject
local new = Instance.new
local datastore = game:GetService("DataStoreService"):GetDataStore("Characters")
local updateAsync = datastore.UpdateAsync
local loadData = function(player)
local id = player.UserId
local data
local success,output = pcall(function()
data = datastore:GetAsync(id)
end)
assert(success,output)
if not data then
data = {
Characters = {},
EquippedCharacter = "",
leaderstats = {}
}
end
if not data.leaderstats then
data.leaderstats = {}
end
for _,v in pairs(data.Characters) do
local value = new("StringValue")
value.Parent = player.Characters
value.Name = v
end
for _,v in pairs(player.leaderstats:GetChildren()) do
if data.leaderstats[v.Name] then
v.Value = data.leaderstats[v.Name]
end
end
player.EquippedCharacter.Value = data.EquippedCharacter
end
local saveData = function(player)
local id = player.UserId
local data = {
Characters = {},
EquippedCharacter = "",
leaderstats = {}
}
for _,v in pairs(player.Characters:GetChildren()) do
table.insert(data.Characters,v.Name)
end
for _,v in pairs(player.leaderstats:GetChildren()) do
data.leaderstats[v.Name] = v.Value
end
data.EquippedCharacter = player.EquippedCharacter.Value
local success,output = pcall(updateAsync,datastore,id,function(old)
return data
end)
assert(success,output)
end
local ChangeChar = function(player,charModel)
player:LoadCharacter()
local currentChar = player.Character
local pos = currentChar.PrimaryPart.CFrame
local Animate = charModel:FindFirstChild('Animate')
local health = charModel:FindFirstChild('Health')
local curAnimate = currentChar:FindFirstChild('Animate')
local curHealth = currentChar:FindFirstChild('Health')
if not health and curHealth then
curHealth:Clone().Parent = charModel
curHealth:Destroy()
end
charModel.Name = player.Name
charModel.Parent = workspace
player.Character = charModel
charModel.PrimaryPart:SetNetworkOwner(player)
charModel.PrimaryPart.CFrame = pos
if not Animate and curAnimate then
curAnimate:Clone().Parent = charModel
curAnimate:Destroy()
end
if not charModel.Humanoid:FindFirstChildOfClass("Animator") then
local Animator = new('Animator')
Animator.Parent = charModel.Humanoid
end
currentChar:Destroy()
print(currentChar)
for _,v in pairs(StarterCharScripts:GetChildren()) do
if not charModel:FindFirstChild(v.Name) then
v:Clone().Parent = charModel
end
end
ChangeCamSubject:FireClient(player,charModel.Humanoid)
charModel.Humanoid.Died:Connect(function()
wait(game.Players.RespawnTime)
updateChar(player)
end)
end
updateChar = function(player)
local UpdatedChar = game.ReplicatedStorage.Remotes.UpdatedChar
local equippedChar = player.EquippedCharacter.Value
local chars = player.Characters
local curChar = player.Character or player.CharacterAdded:Wait()
local changing = player.ChangingChar
if changing.Value then
repeat wait(0.1) until not changing.Value
end
changing.Value = true
if chars:FindFirstChild(equippedChar) then
local module = game.ServerStorage.Characters:FindFirstChild(equippedChar)
local Smodule = game.ServerStorage.Skins:FindFirstChild(equippedChar)
if module then
local CharMoves = module:FindFirstChild("CharacterMoves")
local char = module:FindFirstChildOfClass("Model")
UpdatedChar:Fire(player, equippedChar)
ChangeChar(player,char:Clone())
for i, Moves in pairs(CharMoves:GetChildren()) do
if Moves:IsA("Folder") then
Moves:Clone().Parent = player.Backpack
end
end
for i, Gui in pairs(CharMoves:GetChildren()) do
if Gui:IsA("ScreenGui") then
Gui:Clone().Parent = player.PlayerGui
end
end
elseif Smodule then
local CharMoves = Smodule:FindFirstChild("CharacterMoves")
local char = Smodule:FindFirstChildOfClass("Model")
UpdatedChar:Fire(player, equippedChar)
ChangeChar(player,char:Clone())
for i, Moves in pairs(CharMoves:GetChildren()) do
if Moves:IsA("Folder") then
Moves:Clone().Parent = player.Backpack
end
end
for i, Gui in pairs(CharMoves:GetChildren()) do
if Gui:IsA("ScreenGui") then
Gui:Clone().Parent = player.PlayerGui
end
end
else
player:LoadCharacter()
end
else
player:LoadCharacter()
end
wait(0.1)
changing.Value = false
end
local onJoin = function(player)
-- // This is where we stored player money.
local stats = new("Folder")
stats.Parent = player
stats.Name = "leaderstats"
-- // This is where we store the purchased character.
local characterfolder = new("Folder")
characterfolder.Parent = player
characterfolder.Name = "Characters"
-- // This is where we store the purchased Skin.
local Skinfolder = new("Folder")
Skinfolder.Parent = player
Skinfolder.Name = "Skins"
-- // Player's currency for the character shop.
local money = new("IntValue")
money.Parent = stats
money.Name = "Money"
money.Value = 0
local Wins = new("IntValue")
Wins.Parent = stats
Wins.Name = "Wins"
Wins.Value = 0
-- // Equipped Character Value
local EquippedCharacter = new("StringValue")
EquippedCharacter.Parent = player
EquippedCharacter.Name = "EquippedCharacter"
local Changing = new("BoolValue")
Changing.Parent = player
Changing.Name = "ChangingChar"
loadData(player)
updateChar(player)
EquippedCharacter.Changed:Connect(function()
updateChar(player)
end)
end
game.Players.PlayerAdded:Connect(onJoin)
game.Players.PlayerRemoving:Connect(saveData)
A small part is edited to get my character’s attacks, but nothing that would cause the cloning, Does anyone have any clue what’s causing it?
(Also the characters are grey because I turned LoadCharacterAppearenceOff