Why isn't this variable properly encapsulating what I'm giving it?

So I’m trying to change players character model to a zombie.

local RS = game:GetService("ReplicatedStorage")

local Zombie = {}
Zombie.__index = Zombie

function Zombie.new(player)
	local self = setmetatable({}, Zombie)
	
    -- character is encapsulated here
	self._char = player.Character
	self._zombieModel = RS.Default

	self:_morph()
	return self
end

function Zombie:_morph()
	self._char = self._zombieModel -- this line does nothing 
	self._zombieModel.Parent = workspace
end

return Zombie

I noticed that the ONLY way for the Zombie:_morph() function to work, I have to pass the player as an argument and use it to reference the character like this:

function Zombie:_morph(player)
	player.Character = self._zombieModel
	self._zombieModel.Parent = workspace
end

What confuses me is that self._char does work if I print it or check if it exists

function Zombie:_morph(player)
	if self._char == player.Character then
		-- this runs
		player.Character = self._zombieModel
		self._zombieModel.Parent = workspace
	end
end

Am I missing something super obvious? Why doesn’t it work when I use the self._char variable?

So I think you’re expecting this:

self._char = self.zombieModel

to change the player’s character model. However, what’s actually going on is the _char field is referencing the player’s character instance, not the property. So with that said, what’s actually going on with the line above is that it’s overriding the value of _char to now become zombieModel. So instead of it referencing the player’s character, it will now reference the zombieModel instance.

Hopefully that makes sense.

1 Like

I can not believe I didn’t think of that. Thanks.

1 Like