Help with E to interact system

And you need CollectionService why exactly?

You literally dont need it. Just set the parent/adornee of the BillboardGui whenever the distance is achieved and then activate the userinputservice func.

But dont I need to have a table of all the intractable objects so that I can set the adornee of the billboard gui to the closest one?

If your designing a generic script and not an individual one per object then make a folder in serverstorage or something containing bool or string values. Set the name or value to the interactable objects path or name. I’d recommed using boolvalues as its simpler.

You can do this all in a script.

local InteractableObjs = {"list em here"}
local Controller = instance.new("Folder") --remember second parameter of instance causes a delay!
Controller.Parent = game:GetService("ServerStorage")

local closest

for i,v in pairs(InteractableObjs) do
    local val = instance.new("BoolValue")
    val.Name = v
    val.Value = false 
end

RunService.Heartbeat:Connect(function()
    -- distancing stuff here
    if distance < num then
        Controller["Closest Obj"].Value = true
        closest = tostring(Controller["Closest Obj"])
    else
         return
    end
    Gui.Adornee = closest
end)

UserInputService.InputBegan ...

Thank you so much!
I will try this out.
Also, I have a question. If I want to make the intractable objects do different things based on what object they are (like welcome to bloxburg) do I require different module scripts for each different object?

I’m offering an alterative method.
Now I like to use math to solve lots of problems so bear with me.

Method I would use:

Fire a ray per Stepped event in front of the player of length desired length l studs and if the ray hits something, check if it has the tag Door, whip up the UI.

local Character = game.Players.LocalPlayer.Character
local HRT = Character:WaitForChild("HumanoidRootPart")
local l = 5 --Arbitrary length I chose
local OpenDoorEvent = nil

local function OpenDoor(Door)
        --whatever you planned to do (tween or whatever)
end


RunSvc.Stepped:Connect(function()
     local Ray = Ray.new(HRT.Position, HRT.CFrame.LookVector * l)
     local Part = workspace:FindPartOnRay(Ray, Character)
     if Part and CollectionSvc:HasTag(Part, "Door") then
        Gui.Adornee = Part --Place gui on the door
        OpenDoorEvent = UserInputService.InputBegan:Connect(function(Input)
             if Input.KeyCode == Enum.KeyCode.E then
                  OpenDoor(Part) --The function for opening the door
             end
         end)
         return
     end
     if OpenDoorEvent ~= nil then --Runs when the above if statement returns false
         OpenDoorEvent:Disconnect() --Cleanup event
     end
end)

I need it for not just a door, but various objects. Will this work for that?

it’s as simple as adding:

... or CollectionSvc:HasTag(Part, "Various Other Tags") then
...
end

Here V V

(Oops, edit)

Not at all.

A module script is literally just an organised way of coding and more efficient in some aspects.

Just define your functions for their purposes. A module script in itself does not define the functioning of all functions!
TOO MANY FUNCTIONINGS AHH xd

Okay thank you! But if you take a look at the first post, I mentioned that I was having problems with collection service. But I will try this code out.Thanks!

So I just make a function for each object’s interaction?

CollectionService is very easy to utilize, if you’re having trouble setting tags in scripts, use the plugin to set the tags before runtime. I forgot its name, but it’s along the lines of “Tag Editor”.

I am already using the plugin, but still there were issues in the code

Yep.

Example of how it would look:

local module = {}

module.FunctionForDoor(function(param1, ...)
    -- stuff
end)

module.FunctionForCooking(function(param1, ...)
    -- stuff
end)

return module

Okay. Thank you for your help! :smile:
I will try out the code and let you know.

Do you need this code to run on more than one script?

The reason you are not getting any objects when you call is quite easy to understand, and it’s part of the elemental nature of client behavior.

You are retrieving and storing a list of all the objects a user can interact with immediately after the LocalScript starts running. This will fundamentally fail, because at that time a great portion of the objects in your game have yet to load.

What you must do is either listen for new objects being added or retrieve the list each time you iterate over it; the latter of which could pose certain performance implications. Implementing either of these solutions should fix your issue in that regard.

PS: You are using CollectionService exactly as it was intended, and I applaud your usage. A lot of developers seem to rely on primitive methods to organize their workspace when it comes to scripted objects.

6 Likes

Thank you! :slightly_smiling_face:
I will remember that the next time I use collection service.

2 Likes