Stubborn Issue with Loading Character

Hello Everyone! It sure has been a while since I last posted on here lol.

I am currently trying to load a custom character upon the player joining. It’s been a while since I did Roblox Game Development so bear with me if this seems like a simple fix but this has been a really stubborn issue.

The issue, in question, is that when I try to load the character, the character does load for a split second, but then it resets back to the default character before the change. The code that attempts to accomplish changing the Character is listed below:

-- Needed modules --
local Character = require(script:FindFirstAncestor("ServerScriptService").Modules.CharacterModules.Character)
local CharacterModel = require(script:FindFirstAncestor("ServerScriptService").Modules.CharacterModules.CharacterModel)

game.Players.PlayerAdded:Connect(function(player)
	local model = CharacterModel.new("DefaultCharacter")
	local character = Character.new(player, model)
	
	character:loadCharacter(game:GetService("ServerStorage"):WaitForChild("CharacterModels"))
end)
local InstanceLoader = require(script.Parent.Parent.UtilityModules.InstanceLoader)

local Character = {}
Character.__index = Character

-- Instantiates a new character that the player can use. characterModel should be of type CharacterModel
-- which comes from another module. player is the Player the character will be applied to.
function Character.new(player, characterModel)
	local character = {}
	setmetatable(character, Character)
	character.__player = player
	character.__characterModel = characterModel
	return character
end

function Character:getPlayer()
	return self.__player
end

function Character:getCharacterModel()
	return self.__characterModel
end

function Character:setCharacterModel(newModel)
	self.__characterModel = newModel
end

-- For characterContainer, input should be where the Character is located. -- 
function Character:loadCharacter(characterContainer)
	local charModel = InstanceLoader.loadItem(characterContainer, self:getCharacterModel():getModel())
	
	if charModel then
		local plr = self:getPlayer()
		
		charModel.Parent = workspace
		plr.Character = charModel
		
		local humanoid = charModel:FindFirstChild("Humanoid")
		
		if humanoid then
			humanoid:SetStateEnabled(Enum.HumanoidStateType.Dead, false)
			humanoid.BreakJointsOnDeath = false
		end
		
		plr:LoadCharacter()
	else
		warn("Character not found.")
	end
	
	print("Loaded Character.")
end

return Character
local CharacterModel = {}
CharacterModel.__index = CharacterModel


function CharacterModel.new(model)
	local newCharacterModel = {}
	newCharacterModel.__model = model
	setmetatable(newCharacterModel, CharacterModel)
	return newCharacterModel
end

function CharacterModel:getModel()
	return self.__model
end

function CharacterModel:setModel(newModel)
	self.__model = newModel
end

return CharacterModel
local InstanceLoader = {}
InstanceLoader.__index = InstanceLoader

function InstanceLoader.loadItem(container, item)
	local instance = container:WaitForChild(item):Clone()
	
	if instance then
		return instance
	else
		warn(item.." not found inside "..container.Name)
		return nil
	end
end

return InstanceLoader

I mainly used module scripts as I find OOP to be more efficient. As I mentioned the character does load but only briefly, the issue is that after the brief appearance of the correct character, the player ends up resetting and going back to their default character. If anyone know’s how one can get around this issue, I would really appreciate if you could give me some advice.

1 Like

Place the character model in StarterPlayer and name it StarterCharacter :smiley::+1:

1 Like

Yes I did that before and it worked, but my goal is I want to do this via scripting because I want to create a system where the player can choose their character and change to that.

1 Like

Oh, I see haha.
I don’t see the need to use OOP in this case.
Maybe you could do something like this:

function SetCharacterModel(Player: Player, Character: Model)
    assert(Character, "Valid character model must be provided.")
    
    local NewModel = Character:Clone()
    NewModel.Parent = workspace
    Player.Character = NewModel
    
    --// ...other things which you may want to do
end
1 Like

OOP is a good method for Roblox scripting because, when done correctly, it makes scripts easier to debug, more maintainable, and more extendable in the future.

I also realized that I do not even need to change the players character to accomplish what I need to accomplish. Thank you for your help though, I appreciate it.

1 Like

The thing is, OOP does not need to be utilized everywhere, for everything.
Sometimes, a functional approach to a problem may be a better solution, but it all depends on the use-case and how scalable the system you’re working on should be.

p.s. Luau isn’t an Object Oriented Language, but mostly a Proxy based language.

1 Like

For a large game, which is a project I am undertaking, OOP is often ideal since it can make a game easier to design in the long run, as well as make it easier to add more features later on through extension without needing to modify existing code, which could potentially introduce bugs in code that was already working fine (this is known as the Open Closed Principle in OOP).

You are right that OOP is not the best design choice in all situations, but for games, especially large games, it is incredibly useful. This is especially the case in the long run.

You’re also right to point out that Lua is not technically an Object Oriented Programming language like C++, Java, and Python are. However, ModuleScripts can and do simulate classes very well, since, technically speaking, a class is like a table that contains functions and variables.

1 Like

I had to assume this line, you’re already assigning your character on top that already loads your appearance and calling this will load the StarterCharacter from the StarterPlayer cuz now it’s below the plr.Character

1 Like

I made a change character system a while back (2-3 years??) and I’m confident it’s not the best way…

But I checked StarterPlayer for any models, delete them, cloned a character model named StarterCharacter to StarterPlayer and loaded character.

Definitely can improve a lot from that but that’s a way of how I did it with my 2 years of scripting knowledge.

1 Like