Accessing an OOP object in another script

I created an OOP script for enemies and I want this tool to run the updateSize function of the enemy when the raycast hits but how do I access that object within the script?

--Server 

caster.RayHit:Connect(function(castObject, result, segmentVelocity, cosmeticBulletObject)
	local hit = result.Instance
	
	if hit.Name == "Head" then
		--????????
	end
end)
--Server
local moduleScript = require(game.ReplicatedStorage.BlueberryEnemy)

while true do
	task.wait(1)
	moduleScript.new()
end
--Module
local blueberryEnemy = {}
blueberryEnemy.__index = blueberryEnemy

local enemyTable = {}

-- Helper Functions
function calculateInitialSize()
	local sizeValue = math.random(1, 100) -- Just to determine whether it will be a small or big sized enemy
	local actualSize = nil
	

	if sizeValue >= 90 then
		actualSize = math.random(10, 20)
		
	else
		actualSize = math.random(1, 5)
	end
	--print(sizeValue)
	--print(actualSize)
	return actualSize
end

function shutDown(self)
	self.Model:Destroy()
end

function updateSize(self)
	self.Size = self.Model.Head.Size
	
	if self.Size >= self.MaxSize then
		shutDown()
	end
end


function blueberryEnemy.new()
	
	local blueberryModel = game.ReplicatedStorage.EnemyModels.Blueberry:Clone()
	blueberryModel.Parent = workspace

	local sizeValue = calculateInitialSize()
	local MaxSizeValue = sizeValue + math.random(1, 10)
	
	local newEnemy = setmetatable({
		Name = "Blueberry",
		Model = blueberryModel,
		Size = sizeValue,
		MaxSize = MaxSizeValue
	}, blueberryEnemy)
	
	blueberryModel.Head.Size = Vector3.new(newEnemy.Size, newEnemy.Size,newEnemy.Size)

	table.insert(enemyTable, newEnemy)
	return newEnemy
end

function blueberryEnemy:UpdateSize()
	updateSize(self)
end

function blueberryEnemy:ShutDown(self)
	shutDown(self)
end


return blueberryEnemy

You need to return a dictionary table and inline function etc on module side:

Code
--Module
local blueberryEnemy = {}
blueberryEnemy.__index = blueberryEnemy

local enemyTable = {}

-- Helper Functions
function calculateInitialSize()
	local sizeValue = math.random(1, 100) -- Just to determine whether it will be a small or big sized enemy
	local actualSize = nil
	

	if sizeValue >= 90 then
		actualSize = math.random(10, 20)
		
	else
		actualSize = math.random(1, 5)
	end
	--print(sizeValue)
	--print(actualSize)
	return actualSize
end

function shutDown(self)
	self.Model:Destroy()
end

function updateSize(self)
	self.Size = self.Model.Head.Size
	
	if self.Size >= self.MaxSize then
		shutDown()
	end
end



function blueberryEnemy:UpdateSize()
	updateSize(self)
end

function blueberryEnemy:ShutDown(self)
	shutDown(self)
end

--You dont really need to unwrap constructor like that btw
return {
new = function()
local blueberryModel = game.ReplicatedStorage.EnemyModels.Blueberry:Clone()
	blueberryModel.Parent = workspace

	local sizeValue = calculateInitialSize()
	local MaxSizeValue = sizeValue + math.random(1, 10)
	
	local newEnemy = setmetatable({
		Name = "Blueberry",
		Model = blueberryModel,
		Size = sizeValue,
		MaxSize = MaxSizeValue
	}, blueberryEnemy)
	
	blueberryModel.Head.Size = Vector3.new(newEnemy.Size, newEnemy.Size,newEnemy.Size)

	table.insert(enemyTable, newEnemy)
	return newEnemy
end;
updateSize=updateSize;
}

On Script side:

local moduleScript = require(game.ReplicatedStorage.BlueberryEnemy)
local new = moduleScript.new
local updateSize = moduleScript.updateSize

local Enemy = new()
updateSize()



1 Like

I see you already have an enemyTable, instead of doing table.insert(enemyTable, newEnemy) upon enemy creation, do enemyTable[blueberryModel] = newEnemy instead.

Then create a new method that returns the object given a character:

function blueberryEnemy.GetEnemyFromCharacter(char)
    return enemyTable[char]
end

Then whenever you need to get the enemy object, you can do:

local BlueberryEnemy = require(the module script)
local char = get the character from the hit part
local enemyObject = BlueberryEnemy.GetEnemyFromCharacter(char)

Don’t forget to remove it from the table in the shutDown function

2 Likes