Cannot find value I'm sure is there

My first shot at OOP in Roblox is starting off right. On line 25 of the Enemy object (the only line inside of Enemy:MoveTo()), there’s an exception:

22:29:10.795 - ServerStorage.Enemy:25: attempt to index field 'EnemyModel' (a nil value)

Weird part is, the method that calls Enemy:MoveTo() uses EnemyModel, so if it really didn’t exist, then why would Enemy:Move() be working?

Enemy Object

local Enemy = {}
Enemy.__index = Enemy

function Enemy:Move()
	--Get all the player in line of sight
	--Find closest player
	--Charge player
	local closest = {nil, nil} -- closest[1] = player, closest[2] = distance
	for _,player in pairs(game.Players:GetChildren()) do
		--Add check to see if the zombie is within line of sight of the player
		if player.Character then
			local dist = (player.Character.PrimaryPart.Position - self.EnemyModel.PrimaryPart.Position).magnitude
			if closest[2] == nil or dist < closest[2] then closest = {player, dist} end
	if closest[1] == nil then return end

function Enemy:MoveTo(pos)

	local enemy = { --enemy fields
		EnemyModel = enemyModel
	setmetatable(enemy, Enemy) --enemy methods
	enemyModel.Name = "" --get rid of the nametag
	return enemy

return Enemy

Zombie Object

local Enemy = require(game.ServerStorage.Enemy)

local Zombie = {}
Zombie.__index = Zombie
setmetatable(Zombie, Enemy)

	local zombie =
	setmetatable(zombie, Zombie)
	--Zombie animation, make the arms go up
	local animation ="Animation")
	animation.AnimationId = ""
	return zombie

return Zombie

Zombie script

local zombie = require(game.ServerStorage.Zombie).new(script.Parent)

while true do
1 Like

This is a very simple problem which many people tend to make.

You should use the WaitForChild function, if that doesn’t work then let me know.

Generally, if you’re sure there is a model, you use Parent:FindFirstChild(ModelName), which will either return the model or return nil. WaitForChild can and will yield if the script doesn’t find anything.

That wouldn’t make sense because the zombie script, the script making an instance of Zombie, is inside of zombie model and wouldn’t change anything. I still changed

local zombie = require(game.ServerStorage.Zombie).new(script.Parent)


local zombie = require(game.ServerStorage.Zombie).new(script.Parent.Parent:WaitForChild(script.Parent.Name))

to no effect.

This has been a test and you all fail. As per usual I figured it out by myself at random.

The reasoning is because I’m calling Enemy:MoveTo() as if it were a static method (to those who don’t know OOP lingo, that is a function of an object that can be run without the object being instanced. See all of the table functions). Simply change the line calling Enemy:MoveTo() to self:MoveTo() and the problem is solved.