Character Change

ok so is there a simple way to change character ? (change the model in-game)

i really want it but i dont know how to change it

what i want is when your leaderstats value == 1 then your character will be the character 1 (example) .

so is there a simple way to do this ?

show some example script if possible

1 Like

It’s very difficult to change an Individual Player’s character model.

Here’s a resource with a possible solution. There isn’t an example script you would have to figure out how to recreate the desired effect by going by what’s instructed in the solution.

3 Likes

First off, to do the Leaderstat-based characters, what I would do is start by making folders, (numbered like 1,2 etc) with the characters inside them. Place them in Replicated Storage. Make sure every part of each character is unanchored, and make sure they all have a local animation script. Then, make all your if statements locally, and once one is reached, send a remote event to the server to change the players character to the character in the folder that corresponds with the leaderstat number.

Then do something like this in a Script placed in ServerScriptService:

local debounce = false
YourEvent.OnServerEvent:Connect(function(player, leaderstatval)
if player and debounce == true then
	
	debounce = false
	local folder = game.ReplicatedStorage:FindFirstChild(leaderstatval)
local charClone = folder.Char:Clone(
		charClone.Name = player.Name
		player.Character = charClone
	local humRootPart = charClone:FindFirstChild("HumanoidRootPart")
	local plrRoot = object.Parent:FindFirstChild("HumanoidRootPart")
	if humRootPart and plrRoot then
		humRootPart.CFrame = plrRoot.CFrame
	end
	charClone.Parent = workspace
end
end)

And to make sure that this change stays even over death, place this inside the same ServerScript.
You will need a second Remote Event to get the player’s leaderstat, and a local script which i will show after the following script.

game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
local leaderstatval = YourSecondEvent:FireClient(plr)
if player and debounce == true then
	
	debounce = false
	local folder = game.ReplicatedStorage:FindFirstChild(leaderstatval)
local charClone = folder.Char:Clone()
		charClone.Name = player.Name
		player.Character = charClone
	local humRootPart = charClone:FindFirstChild("HumanoidRootPart")
	local plrRoot = object.Parent:FindFirstChild("HumanoidRootPart")
	if humRootPart and plrRoot then
		humRootPart.CFrame = plrRoot.CFrame
	end
	charClone.Parent = workspace
end
end)
end)

Then, in a local script in StarterPlayerScripts;

local YourSecondEvent = game.ReplicatedStorage.YourSecondEvent
local player = game.Players.LocalPlayer
YourSecondEvent:OnClientEvent:Connect(function()
local LeaderstatVal = player.leaderstats.YourLeaderstatValue
return LeaderstatVal
end)

Phew! That was a lot of typing. Hope this helps!

2 Likes

i have a question , what is the object ?

local debounce = false
YourEvent.OnServerEvent:Connect(function(player, leaderstatval)
if player and debounce == true then
	
	debounce = false
	local folder = game.ReplicatedStorage:FindFirstChild(leaderstatval)
local charClone = folder.Char:Clone(
		charClone.Name = player.Name
		player.Character = charClone
	local humRootPart = charClone:FindFirstChild("HumanoidRootPart")
	local plrRoot = object.Parent:FindFirstChild("HumanoidRootPart") -- this part , the object is?
	if humRootPart and plrRoot then
		humRootPart.CFrame = plrRoot.CFrame
	end
	charClone.Parent = workspace
end
end)
1 Like

so the finished script should be like this or not ? my brain is melting...

server script

local CharEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("CharEvent")

local debounce = false
CharEvent.OnServerEvent:Connect(function(player, Characters)
	if player and debounce == true then

		debounce = false
		local folder = game.ReplicatedStorage:FindFirstChild("Characters")
		local charClone = folder.Engineer:Clone()
			charClone.Name = player.Name
			player.Character = charClone
			local humRootPart = charClone:FindFirstChild("HumanoidRootPart")
			local plrRoot = object.Parent:FindFirstChild("HumanoidRootPart")
			if humRootPart and plrRoot then
				humRootPart.CFrame = plrRoot.CFrame
			end
			charClone.Parent = workspace
	end
end)

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		local leaderstatval = CharEvent:FireClient(plr)
		if plr and debounce == true then

			debounce = false
			local folder = game.ReplicatedStorage:FindFirstChild(leaderstatval)
			local charClone = folder.Char:Clone()
			charClone.Name = plr.Name
			plr.Character = charClone
			local humRootPart = charClone:FindFirstChild("HumanoidRootPart")
			local plrRoot = object.Parent:FindFirstChild("HumanoidRootPart")
			if humRootPart and plrRoot then
				humRootPart.CFrame = plrRoot.CFrame
			end
			charClone.Parent = workspace
		end
	end)
end)

local script

local CharEvent = game.ReplicatedStorage.RemoteEvents:WaitForChild("CharEvent")

local debounce = false
CharEvent.OnServerEvent:Connect(function(player, Characters)
	if player and debounce == true then

		debounce = false
		local folder = game.ReplicatedStorage:FindFirstChild("Characters")
		local charClone = folder.Engineer:Clone()
			charClone.Name = player.Name
			player.Character = charClone
			local humRootPart = charClone:FindFirstChild("HumanoidRootPart")
			local plrRoot = object.Parent:FindFirstChild("HumanoidRootPart")
			if humRootPart and plrRoot then
				humRootPart.CFrame = plrRoot.CFrame
			end
			charClone.Parent = workspace
	end
end)

game.Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function(char)
		local leaderstatval = CharEvent:FireClient(plr)
		if plr and debounce == true then

			debounce = false
			local folder = game.ReplicatedStorage:FindFirstChild(leaderstatval)
			local charClone = folder.Char:Clone()
			charClone.Name = plr.Name
			plr.Character = charClone
			local humRootPart = charClone:FindFirstChild("HumanoidRootPart")
			local plrRoot = object.Parent:FindFirstChild("HumanoidRootPart")
			if humRootPart and plrRoot then
				humRootPart.CFrame = plrRoot.CFrame
			end
			charClone.Parent = workspace
		end
	end)
end)

The local script should not have the game.players.playeradded, the server script should. ( placed in serverscriptservice)

And I forgot to change my script from what I did in studio. The object should be declared as the player’s character, like this:

game.Players.PlayerAdded:Connect(function(plr)
Local object = plr.Character
—rest of script follows

Hi, friendly code reviewer here.

Just wanted to point out that are multiple glaring issues with the character model swapping code you provided that would prevent it from being functional at all, including improper usage of debounce, RemoteEvents where RemoteFunctions should be used instead, among other quirks.

For starters, the debounce you are using to limit the rate of RemoteEvents is kept as a global variable irrespective of the player firing the event, meaning that all players will share the same debounce. Problems would arise if multiple people fired the event simultaneously. Aside from that, the debounce is never actually set to true, so the code would never run. You should throttle the rate for individual players.

Moving to the networking pieces, as I mentioned you’re using a RemoteEvent where you intended to use a RemoteFunction. The difference is that RemoteFunctions return something, RemoteEvents do not. It’s the difference between FireClient and InvokeClient.

This is actually a minor detail when you consider that it doesn’t need to be done at all. To fetch the Player’s leaderstats from the client is not necessary because the server already knows the contents of the Player’s leaderstats folder. It can simply reference game.Player.leaderstats. Regardless of that fact, the client should never hold the master copy of any information that is trusted by the server, because it could be spoofed by exploiters and the server wouldn’t know any better. So, hypothetically, if that information was being kept in some form on the client, asking for it on the server would be considered a blasphemous networking practice.

When it comes to the actual swapping of the character model, you’re doing so within a listener of the CharacterAdded event, which I believe will crash the entire game, since every time you set plr.Character to a non-nil value, the CharacterAdded event fires. Aside from that, you’re checking object.Parent for a HumanoidRootPart rather than the object itself. This code is redundant as well, since it exists in two places. Attempt to follow the DRY (Don’t Repeat Yourself) principle, and use a single function in cases like this.

@HHeartlessHunteR I would not use the above code as a learning resource. I’m not trying to be abrasive AT ALL with my criticism, I just want to stress that the code is objectively malfunctional and will not serve any of your needs, aside from imparting the knowledge that the player’s character can be swapped by simply saying player.Character = newCharacterModel and writing a local controller for the client to move it around (or using Roblox’s default animation scripts if your entity shares enough similarity with a default rig).

1 Like

Jeez, Yeah I messed up there didnt I. I forgot to add things to stop the CharacterAdded Events from firing… Whoops. I guess i wasnt thinking there. Thanks for the constructive feedback… :sweat_smile: I plan to re-do this code in working order.

1 Like

No worries, all part of the learning process! We derive the best lessons from mistakes.

1 Like

Would you look at that, i did learn something!
I fixed the code in the file below.
Change.rbxl (36.0 KB)

Thanks again for your feedback, @Soybeen

1 Like

its working !! thanks for the help :slight_smile:

No Problem! I hope you can do what you want with it!

1 Like