Is there a cleaner way to write this? (E to interact system)

Fairly simple - the code has 2 sections: detecting an E input key, and a block for displaying a BillboardGui (E to interact).

As you can see, in both sections, it is quite repetitive. Is there a cleaner way of doing these things with the different tags? Especially the RenderStepped block, as the only thing that differs for each tag is the GUI text.

Important: should not really sacrifice efficiency.

UIS.InputBegan:Connect(function(input, gameProcessed)
	if input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.E and not gameProcessed then

			for _,Interactable in pairs(CS:GetTagged("ATM")) do
				--if CS:HasTag(Interactable, "ATM") then
					local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude

					if Magnitude <= INTERACTION_RANGE then
						E.TextColor3 = Color3.fromRGB(209, 150, 101)
						ATM_Event:Fire()
						wait(0.1)
						E.TextColor3 = Color3.fromRGB(255, 255, 255)
					end
				--end
			end
			
			for _,Interactable in pairs(CS:GetTagged("Vote")) do
				local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude

				if Magnitude <= INTERACTION_RANGE then
					E.TextColor3 = Color3.fromRGB(209, 150, 101)
					votingGuiEvent:FireServer("get_gui")
					wait(0.1)
					E.TextColor3 = Color3.fromRGB(255, 255, 255)
				end
			end
			
			for _,Interactable in pairs(CS:GetTagged("GunShop")) do
				local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude

				if Magnitude <= INTERACTION_RANGE then
					E.TextColor3 = Color3.fromRGB(209, 150, 101)
					moneySystemEvent:FireServer("gun_shop_gui")
					wait(0.1)
					E.TextColor3 = Color3.fromRGB(255, 255, 255)
				end
			end
		end
	end	
end)

game:GetService("RunService").RenderStepped:Connect(function()
	promptFrame.Visible = false

	for _,Interactable in pairs(CS:GetTagged("ATM")) do
		--if CS:HasTag(Interactable, "ATM") then
			if game.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then -- in case player falls off map
				local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude

				if Magnitude <= INTERACTION_RANGE then
					IS_GUI.Adornee = Interactable
					promptText.Text = "Access ATM"
					promptFrame.Visible = true
				end
			end
		--end
	end
		
	for _,Interactable in pairs(CS:GetTagged("Vote")) do
		--if CS:HasTag(Interactable, "Vote") then
			if game.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then
				local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude

				if Magnitude <= INTERACTION_RANGE then
					IS_GUI.Adornee = Interactable
					promptText.Text = "Cast Vote"
					promptFrame.Visible = true
				end
			end
		--end
	end
	
	for _,Interactable in pairs(CS:GetTagged("GunShop")) do
		if game.Players.LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then
			local Magnitude = (Interactable.Position - game.Players.LocalPlayer.Character.HumanoidRootPart.Position).magnitude

			if Magnitude <= INTERACTION_RANGE then
				IS_GUI.Adornee = Interactable
				promptText.Text = "Browse"
				promptFrame.Visible = true
			end
		end
	end
end)```

Try this:

--//Services
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

--//Variables
local LocalPlayer = Players.LocalPlayer

--//Functions
local function Check1(interactable, event, parameters)
	local Magnitude = LocalPlayer.Character and (interactable.Position - LocalPlayer.Character.HumanoidRootPart.Position).Magnitude

	if Magnitude <= INTERACTION_RANGE then
		E.TextColor3 = Color3.fromRGB(209, 150, 101)
		
		if event:IsA("RemoteEvent") or event:IsA("RemoteFunction") then
			event:FireServer(parameters or nil)
		end
		
		if event:IsA("BindableEvent") or event:IsA("BindableFunction") then
			event:Fire(parameters or nil)
		end
		
		task.wait(0.1)
		E.TextColor3 = Color3.fromRGB(255, 255, 255)
	end
end

local function Check2(interactable, text)
	if LocalPlayer.Character and LocalPlayer.Character:FindFirstChild("HumanoidRootPart") then
		local Magnitude = (interactable.Position - LocalPlayer.Character.HumanoidRootPart.Position).Magnitude

		if Magnitude <= INTERACTION_RANGE then
			IS_GUI.Adornee = interactable
			promptText.Text = text
			promptFrame.Visible = true
		end
	end
end

UIS.InputBegan:Connect(function(input, gameProcessed)
	if input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode == Enum.KeyCode.E and not gameProcessed then
		for _, Interactable in ipairs(CS:GetTagged("ATM")) do
			Check1(Interactable, ATM_Event)
		end

		for _, Interactable in ipairs(CS:GetTagged("Vote")) do
			Check1(Interactable, votingGuiEvent, "get_gui")
		end

		for _, Interactable in ipairs(CS:GetTagged("GunShop")) do
			Check1(Interactable, moneySystemEvent, "gun_shop_gui")
		end
	end
end)

RunService.RenderStepped:Connect(function()
	promptFrame.Visible = false

	for _, Interactable in ipairs(CS:GetTagged("ATM")) do
		Check2(Interactable, "Access ATM")
	end

	for _, Interactable in ipairs(CS:GetTagged("Vote")) do
		Check2(Interactable, "Cast Vote")
	end

	for _, Interactable in ipairs(CS:GetTagged("GunShop")) do
		Check2(Interactable, "Browse")
	end
end)

Why are you writing your own code if you can just use ProximityPrompts? You can even change their appearance.

2 Likes

The proximity prompts can not be customized much though, that’s maybe why he’s using a custom one. Along with the fact you can edit the functions and properties of custom ones much more.

1 Like

I actually had no idea ROBLOX provides ProximityPrompt - thanks. Seems like popular games use that default UI too. Nevertheless, I’ll probably stick with my own system for now as I’m only developing for PC at the moment.

If you use the proximity prompt service.
Take a look at this: ProximityPrompt.Style
I enjoy using that as a frame then writing and designing my own. You can customize as much as you want really.

Oh, didn’t know there was that much customizability, thanks for telling me.

1 Like