Getting object associated with an instance in a separate class

In my game, I have two classes “Moveable” and “StackBottom” when both of these classes are instantiated, an instance is passed into the constructor which is the instance that these classes will act upon (create connections on, call methods on, etc.). When Moveable is instantiated, the tag “Moveable” is added to the instance using CollectionService. When StackBottom is instantiated, a hitbox is created which when touched will check if the part that touched it is a Moveable by checking if the instance has the tag “Moveable”.

I need to access the Moveable object that the instance is attached to within the StackBottom class in order to run a few sanity checks. However, I can’t think of a clean way to do so. Creating a ModuleScript that holds a dictionary of all objects in the game where the key is the instance and the value is the object seems stupid to me.

What would be the best way of going about this?

(Removed code not related to the question)
Moveable class:

local MoveableClient = {}
MoveableClient.__index = MoveableClient

function MoveableClient.new(model: Model): table
    local self = setmetatable({}, MoveableClient)

    self.model = model
    CollectionService:AddTag(self.model, "Moveable")
    
    self.isHovering = false -- I want to access these properties in the StackBottom class
    self.isPickedUp = false

    return self
end

return MoveableClient

StackBottom class:

local StackBottom = {}
StackBottom.__index = StackBottom

function StackBottom.new(model: Model)
    local self = setmetatable({}, StackBottom)

    self.janitor = Janitor.new()

    self.model = model
    self.ghostItem = nil
    self.ghostItemStackable = nil

    local modelCFrame, modelSize = self.model:GetBoundingBox()

    self.hitBox = Instance.new("Part")
    self.hitBox.Size = Vector3.new(7, 7, 7)
    self.hitBox.CFrame = modelCFrame
    self.hitBox.Transparency = 1
    self.hitBox.CanCollide = false

    local weld = Instance.new("WeldConstraint")
    weld.Part0 = self.hitBox
    weld.Part1 = self.model.PrimaryPart
    weld.Parent = self.hitBox
    self.hitBox.Parent = self.model

    self.janitor:Add(RunService.RenderStepped:Connect(function()
        local partsInHitbox = workspace:GetPartsInPart(self.hitBox)
        if not self.ghostItem then
            for _, part: Part in ipairs(partsInHitbox) do
                if CollectionService:HasTag(part.Parent, "Moveable") then -- Checking tag here
                    self:_AddGhostStack(part.Parent)
                end
            end
        else
            local ghostItemInRange = false
            for _, part: Part in ipairs(partsInHitbox) do
                if part.Parent == self.ghostItemStackable then
                    ghostItemInRange = true
                end
            end

            if not ghostItemInRange then
                self:_RemoveGhostStack()
            end
        end
    end))

    return self
end

return StackBottom

I don’t think there is any other way besides a handler or manager of instances.

local MoveableClient = {}
MoveableClient.__index = MoveableClient
MoveableClient.Moveables = {}

function MoveableClient.new(model: Model): table
    local self = setmetatable({}, MoveableClient)

    self.model = model
    CollectionService:AddTag(self.model, "Moveable")
    
    self.isHovering = false -- I want to access these properties in the StackBottom class
    self.isPickedUp = false

    MoveableClient.Moveables[model] = self

    return self
end
            for _, part: Part in ipairs(partsInHitbox) do
                if CollectionService:HasTag(part.Parent, "Moveable") then -- Checking tag here
                    local moveable = MoveableClient.Moveables[part.Parent]
                    ...
                end
            end

I was thinking about this but I’m not sure if it’s the best way to do so. If I wanted to do this for multiple classes I would have to create a ModuleScript for every single class and store the objects there. I feel like this is a pretty common issue with a much cleaner solution.

For anybody with this issue in the future, I solved it using the Binder pattern. It’s a neat pattern that connects CollectionService and OOP together and allows you to bind classes to roblox instances using CollectionService tags. It was featured in “5 Powerful Code Patterns Behind Roblox Games” during RDC 2020.

Skip to 31:05 for the talk on Binders. Although I highly recommend watching the entire talk as it features some extremely useful information from some of the top developers on the platform.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.