OOP interaction system not working?

I am trying to make a interaction system with OOP, however I ran into a problem, the script does not print anything when I tried to debug it either. No errors))

Module script:


local Interactions = {}

Interactions.__index = Interactions
function Interactions.new(interactionPart, range, humanoidroot, debounce)
    local InteractionItems = {}
    setmetatable(Interactions, InteractionItems)
    
    InteractionItems.range = range
    InteractionItems.humanoidroot = humanoidroot
    InteractionItems.debounce = debounce
    InteractionItems.interactionPart = interactionPart
    
    game:GetService("UserInputService").InputBegan:Connect(function(input, GPE)
        if not GPE and input.KeyCode == Enum.KeyCode.E then
            if (humanoidroot.Position - interactionPart.Position) > range then
                debounce = true
                print("HO")
            end
        end
    end)
    return InteractionItems
end
function Interactions:Cook(Tool, humanoid, debounce)
print("Ha")
    if debounce then
        humanoid:EquipTool(Tool)
    end
end

Serverscript:

local Interactions = require(game.ReplicatedStorage.Interactions)
local player = game.Players.LocalPlayer
local Character = player.Character or player.CharacterAdded:Wait()
local humanoidrootpart = Character:WaitForChild("HumanoidRootPart")
local humanoid = Character:WaitForChild("Humanoid")
local debounce = false
local tool = game.ReplicatedStorage.Others.Tool:Clone()
local Oven = Interactions.new(workspace.OvenPart, 5, humanoidrootpart, debounce)
Oven:Cook(tool, humanoid, debounce)

I recommend using https://youtu.be/gH46LyDyZq0 this. I have used it it’s act super helpful and worked for my self.

Thing is, I’m just trying to create classes for different objects I am interacting with, I could just duplicate a function detecting range and UserInputService, however it just looks messy and clustered.

It looks like you have the parameters in the wrong order of the setmetatable method.

If I’m not mistaken, I think you want to have Interactions as the metatable you’re setting InteractionItems to.

e.g:

setmetatable(InteractionItems, Interactions)

As Interactions is what contains the metamethod.

Edit: Yes, you were right on on that. So sorry for misleading. Apologies.

If the module is on the server it cannot read user input.

What do you suggest if I’m using OOP? Because aswell as the :Cook() function, it doesn’t print anything. But I’m not sure if that is the reason why EVERYTHING is not working.

Would I just detect in the function if plr in range, fireserver?

(Edit, I tried to use the Modulescript on the client, but nothing works even then, I read the modulescripts work on Client unless I’m wrong.

An oop interaction system is tricky on the client because you don’t want someone getting into the code and say setting all the debounce’s to true. You could fire server with say the interaction instance. Since you tried it on the client make sure your requiring the module in a local script on the client. Your only using this for cooking?

Not just for that, I’m making multiple, “Animations”, (Can’t think of a better word) Using UIS to check if player is in range, do something specific depending on what the player has been in ranged and pressed. I’m not very good with Anticheats or securing my game, what do you mean by firing server with the interaction instance? How would I make it secure enough that exploiters wont be able to exploit it?
E.g (Bad example.)

Player goes to door, does something specific
Player goes to ladder, does something else

try this

if (humanoidroot.Position - interactionPart.Position).magnitude

I’ll attempt to debug your code, but for the meantime I have a critique.


I highly suggest not doing this. Each instance having an individual listener is not a good idea, I’d recommend an outside approach to it.

1 Like

Oh ok I see. You can bring the module back to the server if you want and just not listen for key press. What I recommend on the client is tagging all your interactions into separate tags with Collection service and listening for E press if magnitude is within a certain distance. Then you could have a cache on the server of all the parts and do the proper interaction from there. For example:

--local script on client. I'd put in StarterPlayerScripts

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hrp = char:WaitForChild("HumanoidRootPart")

local CollectionService = game:GetService("CollectionService")
local UIS = game:GetService("UserInputService")

local Remote --Remote Event for interaction

--[[ for the collection service you could tag them all individually by class say if
the interaction part is a door, chair, light, etc... ]]
--Connections so you can disconnect it when removed from collection so no memory leaks
local Connections = {}

for _, part in ipairs(CollectionService:GetTagged("Interaction")) do 
       Connections[part] = UIS.InputBegan:Connect(function(input, gp)
               if gp then return end
               
              if player:DistanceFromCharacter(part.Position) <= range and input.KeyCode == Enum.KeyCide.E then 
              Remote:FireServer(part)
       end)
end

--I wont write it but make sure you connect parts that are added/removed from collectionService. Make sure you connect them to uis when added and disconnect when removed 

--Server-- 
--ModuleScript-- 

local Interactions = {}
Interactions.__index = Interactions

local InteractionPartCache = {}

local CollectionService = game:GetService("CollectionService")

function Interactions.new(part, class)
    local InteractionItems = {}
    setmetatable(InteractionItems, Interactions)
    
    interactionItems.Part = part
    interactionItems.Debounce = false 
    interactionItems.Class = class --door, ladder, light, etc
    InteractionPartCache [part] = interactionItems
    CollectionService:AddTag(part, "Interaction")
end 

--Rest of your logic

--ServerScript-- 

local Remote 
local interactionModule = require(game.ServerScriptService.InteractionModule)
   
--listen for RemoteFire-- 
--Do logic for that part--

Its definitely not a great method that I just wrote but I’m in a rush lol. What I’d suggest is you tag each different class for collectionService. For more info looks here .

1 Like

I’ll give it a shot and get back to you. Thanks for the help.