Character changing for everyone instead of just one player

(Another Topic of me today, will be the last one :smiley: )

So the code i made below is for a Character inventory system, when you press the equip button it equips the character using the code below.

However the problem i had was that when u died/respawned ur character would change back to the default startercharacter. So what i did was change the StarterCharacter to the character u have equipped.

But what happens now, when someone equips a character, the StarterCharacter changes for every player in the game! So everyone turns into the same character.

Is there a way i can only change it for one player while still managing that u keep ur character when u die/respawn

Might be a difficult issue i dont know. Hope someone can help me with it!

	elseif player.CharacterShop.Characters:FindFirstChild(character.Name) and player.CharacterShop.EquippedCharacter.Value ~= character.Name then
		
		local newCharacter = character:Clone()
		newCharacter.Name = player.Name
		player.Character = newCharacter
		newCharacter.Parent = workspace
		
		local newstarterCharacter = character:Clone()
		local oldstartercharacter = game.StarterPlayer.StarterCharacter
		oldstartercharacter:Destroy()
		newstarterCharacter.Name = "StarterCharacter"
		newstarterCharacter.Parent = game.StarterPlayer
		
		
		return "Equip"

You can just change the character skin by using accessories, clothes and optionnaly a humanoid description instead of changing the whole character model.

It is easier, better, and less annoying for the overall gameplay as we are not died/respawning each time you change character.

We are using custom characters so this is different, each character has its own humanoid etc.

So you have to change the whole character?

Maybe instead of parenting the new character to StarterPlayer, parent it to the workspace and set the player’s Character attribute to the new character on spawn.

You could try, just adding a part to the script “CharacterAdded” and once that happens, you can fetch the character that you want and equip it then,

Do you have any example how this would look scripting wise?

Because i made it parent to workspace and have it the players name, this changes the character indeed.

So how would I make it change (keep the character) again on respawn?

You’ll need to check when the character respawns, and when it does, change its character. Pretty sure you can use player.CharacterAdded to do this, and change its character when its triggered with a :Connect(function())
so it’d be

player.CharacterAdded:Connect(function()
    -- change character, I don't know the context of this so I don't really know for this part...
end)

It looks like you are trying to change the StarterCharacter for every player in the game whenever someone equips a character. This is happening because you are setting newstarterCharacter.Parent = game.StarterPlayer . This makes newstarterCharacter the new StarterCharacter for every player in the game, not just for the player that is equipping the character.

To only change the StarterCharacter for a single player, you will need to store the player’s equipped character in a different location. One way to do this is to create a new folder in the player’s PlayerData model and store the equipped character there.

Here is an example of how you could modify your code to achieve this.

if player.CharacterShop.Characters:FindFirstChild(character.Name) and player.CharacterShop.EquippedCharacter.Value ~= character.Name then
	local newCharacter = character:Clone()
	newCharacter.Name = player.Name
	player.Character = newCharacter
	newCharacter.Parent = workspace
	
	-- Create a new folder in the player's PlayerData model to store the equipped character
	local equippedCharactersFolder = Instance.new("Folder")
	equippedCharactersFolder.Name = "EquippedCharacters"
	equippedCharactersFolder.Parent = player.PlayerData
	
	-- Store the equipped character in the new folder
	local equippedCharacter = character:Clone()
	equippedCharacter.Name = "EquippedCharacter"
	equippedCharacter.Parent = equippedCharactersFolder
	
	return "Equip"
end

Then, when the player dies and respawns, you can check if the player has an equipped character stored in their PlayerData , and if so, set it as the player’s character:

local equippedCharactersFolder = player.PlayerData:FindFirstChild("EquippedCharacters")
if equippedCharactersFolder then
	local equippedCharacter = equippedCharactersFolder:FindFirstChild("EquippedCharacter")
	if equippedCharacter then
		player.Character = equippedCharacter:Clone()
	end
end

This way, each player’s equipped character is stored separately and will not affect the equipped characters of other players.

Also, don’t worry about posting lots of devforum posts, its really not that bad to ask for help, and it’ll help you learn the best ways to accomplish somethign (+ it may or may not keep us occupied :P)

1 Like

Ive tried this out and it returns me this error?

Did you reference it correctly?

                                               ⚠️ Warning ⚠️

I’m only trying to help

This code was made by AI

It looks like you are trying to access a folder called PlayerData within the Player object. However, it seems that PlayerData is not a valid member of the Player object.

One possible solution to this issue is to use the PlayerDataStore service to store data about the player. You can use the GetAsync() function of the PlayerDataStore service to retrieve data about the player, and the SetAsync() function to store data about the player.

Here is an example of how you could modify your code to store the equipped character using the PlayerDataStore service.

if player.CharacterShop.Characters:FindFirstChild(character.Name) and player.CharacterShop.EquippedCharacter.Value ~= character.Name then
	local newCharacter = character:Clone()
	newCharacter.Name = player.Name
	player.Character = newCharacter
	newCharacter.Parent = workspace
	
	-- Use the PlayerDataStore service to store the equipped character
	local playerDataStore = game:GetService("DataStoreService"):GetDataStore("PlayerDataStore")
	local success = playerDataStore:SetAsync(player.UserId, character.Name)
	if success then
		return "Equip"
	else
		return "Error"
	end
end

Then, when the player dies and respawns, you can check if the player has an equipped character stored in the PlayerDataStore , and if so, set it as the player’s character:

local playerDataStore = game:GetService("DataStoreService"):GetDataStore("PlayerDataStore")
local equippedCharacterName = playerDataStore:GetAsync(player.UserId)
if equippedCharacterName then
	local equippedCharacter = game.Characters:FindFirstChild(equippedCharacterName)
	if equippedCharacter then
		player.Character = equippedCharacter:Clone()
	end
end
local playerDataStore = game:GetService("DataStoreService"):GetDataStore("PlayerDataStore")
local equippedCharacterName = playerDataStore:GetAsync(player.UserId)
if equippedCharacterName then
	local equippedCharacter = game.Characters:FindFirstChild(equippedCharacterName)
	if equippedCharacter then
		player.Character = equippedCharacter:Clone()
	end
end

I hope this helps! Let me know if you have any questions.

Ive got it to work now only problem im still having is that it loops then gives this error

This is the code now:

local function onCharacterAdded(character)
	print(character.Name .. " has spawned")
	local player = game.Players:GetPlayerFromCharacter(character)
	local equippedCharactersFolder = player:FindFirstChild("EquippedCharacters")
	if equippedCharactersFolder then
		local equippedCharacter = equippedCharactersFolder:FindFirstChild("EquippedCharacter")
		if equippedCharacter then
			local newCharacter = equippedCharacter:Clone()
			newCharacter.Name = player.Name
			player.Character = newCharacter
			newCharacter.Parent = workspace
			print("Character has been equipped")
		end
	end
end

How would i make it that it only occurs once every death/respawn?

The reason why this happens is because CharacterAdded fires every time a character is added to the workspace. In this function, you change the character, which fires it. See the problem? This causes a recursive loop, which gives you this error. You can fix it using a debounce.

local debounce = false

local function onCharacterAdded(character)
	print(character.Name .. " has spawned")
	local player = game.Players:GetPlayerFromCharacter(character)
	local equippedCharactersFolder = player:FindFirstChild("EquippedCharacters")
	
	if debounce == false then
		debounce = true
	
	if equippedCharactersFolder then
		local equippedCharacter = equippedCharactersFolder:FindFirstChild("EquippedCharacter")
		if equippedCharacter then
			local newCharacter = equippedCharacter:Clone()
			newCharacter.Name = player.Name
			player.Character = newCharacter
			newCharacter.Parent = workspace
			print("Character has been equipped")
		debounce = false
		end
	end
	end
end

I have tried adding a debounce, however this just cuts off the scripts after this part:

local function onCharacterAdded(character)
	print(character.Name .. " has spawned")
	local player = game.Players:GetPlayerFromCharacter(character)
	local equippedCharactersFolder = player:FindFirstChild("EquippedCharacters")

Its not returning any errors, or am i just using debounce wrong?

You need an if debounce then. Nothing will actually occur if debounce is true

Didnt i do that here or is this a misunderstanding xd

yes but thats setting it back to true again. you could get rid of debounce entirely and nothing would change.

local debounce = false

local function onCharacterAdded(character)
	print(character.Name .. " has spawned")
	local player = game.Players:GetPlayerFromCharacter(character)
	local equippedCharactersFolder = player:FindFirstChild("EquippedCharacters")
	
	if debounce == false then
		
	if equippedCharactersFolder then
		local equippedCharacter = equippedCharactersFolder:FindFirstChild("EquippedCharacter")
		if equippedCharacter then
			local newCharacter = equippedCharacter:Clone()
			newCharacter.Name = player.Name
			player.Character = newCharacter
			newCharacter.Parent = workspace
			print("Character has been equipped")
		debounce = true
		end
	end
	end
end

When i do this it just clones them over and over again? what im i doing wrong

you aren’t meant to set it to true, you’ve already done that. you’re only meant to run that section of code when debounce is true
now im getting super confused…