This was my first time using collection service and I think it turned out pretty good.
Code:
Server Script
local collectionService = game:GetService("CollectionService")
local tween = require(game.ReplicatedStorage.modules.tween)
for _, part in pairs(collectionService:GetTagged("interaction")) do
local interactGui = game:GetService("ReplicatedStorage").interact:Clone()
interactGui.Parent = part
local inputRem = game.ReplicatedStorage.input
inputRem.OnServerEvent:Connect(function(player, input, camCFrame)
if (part.Position - camCFrame).magnitude < 15 then
local tweenGoals = {
BackgroundColor3 = Color3.new(1, 1, 1)
}
tween.Tween(interactGui.Frame.interactKeyBG, 0.05, "Sine", "InOut", tweenGoals)
wait(0.1)
local tweenGoals = {
BackgroundColor3 = Color3.new(0.270588, 0.270588, 0.270588)
}
tween.Tween(interactGui.Frame.interactKeyBG, 0.1, "Sine", "InOut", tweenGoals)
local interact = require(part.interact)
interact:interact(player)
end
end)
end
Client Script
local uis = game:GetService("UserInputService")
uis.InputBegan:Connect(function(input, GameProcessed)
if input.KeyCode == Enum.KeyCode.F then
local camCFrame = game:GetService("Workspace").CurrentCamera.CFrame.Position
game.ReplicatedStorage.input:FireServer(input, camCFrame)
end
end)
module script (within all parts that are interacted with)
local module = {}
function module:interact(player)
game.ReplicatedStorage.DialogueRemote:FireClient(player, script.Parent.Dialogue)
end
return module
It is definitely bad practice to tween UI on the server. As a general note, it would be much better to handle this completely locally. It doesn’t make sense to needlessly forward arguments between the client and the server when the client doesn’t need data from the server.
A much better way to do this is to store messages/text data in a ModuleScript and then have a LocalScript handle interactions locally with the available data.
GameProcessed is never used, so you shouldn’t include it as an argument.
function module:interact(player)
game.ReplicatedStorage.DialogueRemote:FireClient(player, script.Parent.Dialogue)
end
Doesn’t it make more sense to only return the interact function rather than an otherwise unused table? Do you really need a ModuleScript for this if it is only used once?
Avoid tweening things on the server, particularly UI. UI should always be handled locally. Also, it makes no sense to define a variable for tweenGoals if it is only used once. You should instead define the goal argument inline to avoid unnecessary clutter. Additionally, it is better practice to employ Enums rather than the real values (ie Enum.EasingStyle.Sine).
I’ve learned a lot of things since I made this and I definitely agree with everything you’ve said in this post.
Thanks for the feedack
Also I still had GameProcessed in there from earlier iterations
Doesn’t it make more sense to only return the interact function rather than an otherwise unused table? Do you really need a ModuleScript for this if it is only used once?
Yeah, at the time the only Idea I could come up with was using a module script