E to interact-- while hovering

Hello! I’m trying to make an E to interact system that only works while the mouse is hovering over an interactable. However, i’m having difficulty figuring out how to go about it. I’ve messed around with a script for a while and can’t figure out how to make it work.

I’ve looked around on the forum and all the solutions are content with using proximity prompts, but i’m quite certain i want a hover-over keybind system. It fits what i’m making.

Here’s my current local-code:

local players = game:GetService("Players")
local uis = game:GetService("UserInputService")

clickdetector = script.Parent.ClickDetector
hover = script.Hovering

--detect keypress while hovering, fire event
uis.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.E and hover.Value == true then
		script.Parent.Pressed:FireServer()
	end
end)

--set hover to true while hovering, make interact gui visible
if clickdetector.MouseHoverEnter then
	hover = true 
	players.LocalPlayer.PlayerGui.Main.Interact.Visible = true
end

--set hover to false when leaving hover, make interact gui invisible
if clickdetector.MouseHoverLeave then
	hover = false 
	players.LocalPlayer.PlayerGui.Main.Interact.Visible = false
end

Here’s my current server-code:

debounce = script.Parent.Debounce
enabled = script.Parent.Enabled
pressed = script.Parent.Pressed
click = script.Parent.Click

--when local detects a press, do stuff
pressed.OnServerEvent:Connect(function()
	
	if enabled == false then
		script.Parent.Material = "Neon"
		enabled = true
	else
		script.Parent.Material = "Plastic"
		enabled = false
	end
	
	click:Play()
			
end)
1 Like

its clickdetector.MouseHoverEnter:Connect, its a RBXScriptSignal, not a boolean

1 Like

Okay, I changed my code to:

--set hover to true while hovering, make interact gui visible
clickdetector.MouseHoverEnter:Connect(function()
	hover = true 
	players.LocalPlayer.PlayerGui.Main.Interact.Visible = true
end)

--set hover to true when leaving hover, make interact gui invisible
clickdetector.MouseHoverLeave:Connect(function()
	hover = false 
	players.LocalPlayer.PlayerGui.Main.Interact.Visible = false
end)

It still doesn’t seem to be working. Nothing happens, there arn’t even errors.

1 Like

I’ve found that it’s not even printing anything when i add prints to the hover functions.

1 Like

I suggest using PlayerMouse.Target in a loop to detect what the player’s mouse is hovering over something, rather than a ClickDetector.

1 Like

Apologies, i’m pretty new.
The only loop i’m aware of right now is while true do, and i’m not sure all of my buttons should be checking every second if i’m hovering over them. What loop should i use here?

1 Like

Been messing around with this, and i’m starting to think i should make some kind of “interactable handler” instead, if i’m gonna need tons of interactables checking if you’re hovering over them. Not sure how one would go about that

1 Like

LocalScripts are meant to be in StarterGui, StarterPlayerScripts, StarterCharacterScripts etc.

This won’t even work since parts only accept server sided script, you have to put it inside somewhere else this can work, also one thing is you’re also supposed to use :Connect() for MouseHover events

--inside ScreenGUI
local players = game:GetService("Players")
local uis = game:GetService("UserInputService")

local clickdetector = workspace.path_to_click
local hover = script.Hovering --boolvalue
local interact_txt = script.Parent.Interact --assuming its textlabel, set to script.Parent to disable GUI (script remains running if this is disabled

--detect keypress while hovering, fire event
uis.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.E and hover.Value == true then
		script.Parent.Pressed:FireServer()
	end
end)

--set hover to true while hovering, make interact gui visible
clickdetector.MouseHoverEnter:Connect(function()
	hover.Value = true --you have to assign value if they're a class object
	interact_txt.Visible = true
end)

--set hover to false when leaving hover, make interact gui invisible
clickdetector.MouseHoverLeave:Connect(function()
	hover.Value = false 
	interact_txt.Visible = false
end)
1 Like

I see. If i were to make something similar to my current local script in starterplayer that fired the remote event of interactables, would that theoretically work? I’m trying to make the client trigger server events when they interact, so i’ve got to make the interact system hook up to the scripts inside the interactables

that works but for an interaction system like this, i’d put it on StarterGui since you’re updating the text label visibility in client (so none of the extra work are required by getting player gui, meaning that you just directly make variable and assign it to the screen gui)

1 Like

Oh, i should’ve mentioned, i moved that code-snippet for the GUI visibility to my interactable highlighting script, and it works perfectly. I’m just trying to get the interaction event to trigger now. The visuals of it are functioning as-intended.

If the interaction manager thingy works, i’ll mark that as the solution. You’ll probably hear from me if it doesn’t work though.

1 Like

For anyone that reviews this post: I made an interaction manager in StarterPlayer that, whenever you press E, checks if a part has an Interactable tag and if it does it fires an Interact remote event inside of the interactable. The interactable has a script inside of it that does the server-side of the interaction when it’s clicked.

Very easy base to work off of and customize

1 Like

I got a method that will work for you. Insert a module script on every interactable part.

Once the mouse moves, it will raycast to the new hit, where it would look for an interaction moduleScript, if it finds one it should require it.

The moduleScripts must have these 3 base functions:

.onFrame: Client calls this function every heartbeat
.onHover: Fired when the hover starts
.onKeyPress: fired when the user presses a key

Here’s an example of one of my moduleScripts for an interactable part:

local items = script.Parent.items
local cannon = script.Parent

local interaction = {}

local w_int = game.ReplicatedStorage.weapon_interactions
local dMouse = require(game.ReplicatedStorage.client_bindable.byMouse)

local rHex = "#DD3333"

local function fil2(n:number)
	local split = tostring(math.round(n*10)/10):split(".")
	split[2] = split[2] or "0"
	return split[1].."."..string.sub(split[2], 1)
end
interaction.atHover = function()
	local firstText = ""
	if items.gunpowder.Value >= 1 then
		if items.cannonball.Value >= 1 then
			firstText = "Press F to fire the cannon!"
		else
			firstText = "This cannon is not equiped with a cannonball, insert one in!"
		end
	else
		firstText = "The cannon is out of gunpowder, refill it!"
	end
	
	local pitch = math.round(-math.deg(select(3, cannon.cannon:GetPivot():ToOrientation()))*10)/10
	local t = 		
		{
			firstText,
			"Press Q or E to toggle cannon pitch.",
			"Pitch: "..fil2(pitch).."°"
		}
	if cannon.inCooldown.Value then
		table.insert(
			t, 
			1, 
			'<font color="'..rHex..'">COOLDOWN! ('..fil2(cannon.inCooldown.secs.Value)..'s)</font>')
	end
	return t
end

local rnd = function(n, t)
	return math.round(n / t) * t
end

interaction.triUpdate = function()
	local firstText = ""
	if items.gunpowder.Value >= 1 then
		if items.cannonball.Value >= 1 then
			firstText = "Press F to fire the cannon!"
		else
			firstText = "This cannon is not equiped with a cannonball, insert one in!"
		end
	else
		firstText = "The cannon is out of gunpowder, refill it!"
	end

	local pitch = -math.deg(select(3, cannon.cannon:GetPivot():ToOrientation()))
	local t = 		
		{
			firstText,
			"Press Q or E to toggle cannon pitch.",
			"Pitch: "..fil2(pitch).."°"
		}
	if cannon.inCooldown.Value then
		table.insert(
			t, 
			1, 
			'<font color="'..rHex..'">COOLDOWN! ('..fil2(cannon.inCooldown.secs.Value)..'s)</font>')
	end
	dMouse(t)
end

interaction.atkeypress = function(key:Enum.KeyCode)
	if table.find({Enum.KeyCode.Q, Enum.KeyCode.E}, key) then
		local mod = 1 if key == Enum.KeyCode.E then mod = -1 end
		w_int.pitch_cannon:FireServer(cannon,7.5 * mod) return
	end
	if key == Enum.KeyCode.F then
		w_int.fire_cannon:FireServer(cannon)
	end
end

return interaction
1 Like

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