Check if a player has looked away from a part

Hi, I’m trying to make a highlight-select function for some parts in my game, although I had a problem disabling the highlight when the player looks away from the part

Here is my script as it is now:

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")

local function createHighlight(part)
	local highlight = Instance.new("Highlight")
	highlight.FillTransparency = 1
	highlight.Adornee = part
	highlight.Parent = part
	return highlight
end

local function checkAndHighlight(part)
	local existingHighlight = part:FindFirstChildOfClass("Highlight")

	if existingHighlight then
		existingHighlight.Parent = part
	else
		local newHighlight = createHighlight(part)

		local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.Out, 0, false, 0)
		local whiteTween = TweenService:Create(newHighlight, tweenInfo, { OutlineColor = Color3.new(1, 1, 1) })
		local greyTween = TweenService:Create(newHighlight, tweenInfo, { OutlineColor = Color3.new(0.5, 0.5, 0.5) })

		whiteTween:Play()
		whiteTween.Completed:Connect(function()
			greyTween:Play()
		end)
		greyTween.Completed:Connect(function()
			whiteTween:Play()
		end)
		whiteTween:Play()
	end
end

local function onHover(input, gameProcessedEvent)
	if gameProcessedEvent then
		return
	end

	local mouseTarget = Players.LocalPlayer:GetMouse().Target
	if mouseTarget and mouseTarget:HasTag("Interactable") then
		checkAndHighlight(mouseTarget)
	end
end

local function onRenderStepped()
    local mouse = Players.LocalPlayer:GetMouse()

    local mouseTarget = mouse.Target
    if not (mouseTarget and mouseTarget:IsA("Part") and mouseTarget:HasTag("Interactable")) then
        for _, part in pairs(workspace:FindPartsInRegion3(workspace.CurrentCamera.CFrame.Position, Vector3.new(100, 100, 100), nil)) do
            if part:IsA("Highlight") then
                part.Parent = nil
            end
        end
    end
end

game:GetService("RunService").RenderStepped:Connect(onRenderStepped)

The current error is:
“Unable to cast Vector3 to Region3 - Client - LocalScript:52”

Any help is appreciated, thanks!

2 Likes

Do you want the script to highlight objects visible in the player’s camera? Or do you want to make it so that objects that are hovered over by mouse are highlighted?

2 Likes

I only want objects highlighted when the player’s mouse is hovering over them.

2 Likes

Add a clickdetector and place a script in it, make a new highlighter instance in the code and set it’s parent to “nil” and adornee to the part you want it to adornee to. Then, make two functions, one detecting when the mouse hovers over the part, and the other detecting when the mouse stops hovering over the part, then in the former, set the parent of the highlighter instance to “workspace” and in the latter set the highlighter instance’s parent to “nil”.
You’re welcome!

P.S: Your code is overcomplicated, it didn’t even take me 10 minutes to figure this one out. You need to think simple before you think complex.

2 Likes

Thank you, I often overcomplicate things by only thinking over things at first glance, if I put a little more thought, 10 lines could turn into 2 or 3.

2 Likes

I’m not gonna solve your error but what I suggest is every frame on clientside see if mouse.target is a part you can highlight, if it is create a highlight parented to a folder and highlight it, else nothing. also every frame delete all highlights that are not attached to the current mouse.target. Put all highlights in a folder to easily access them, use the adornee feature to check what part it’s attached to. To figure out which parts can be highlighted, I suggest using the new “Tags” feature roblox added. Put a tag for “CanBeHighlighted” or something and just check for that.

2 Likes

This is simple. You can use :Dot with the LookVector of the camera, and the LookVector of the Unit of the Object.Position - camera.CFrame.Position.

Here’s a reference on :Dot

Here’s an example:

local camera = workspace.CurrentCamera
local character = --

local object = workspace.Object

local objectUnit = (object.Position - camera.Position).Unit

local dot = camera.CFrame.LookVector:Dot(objectUnit)

print(dot)

if dot < 0 then print("Looking away!") end
3 Likes

I think my answer is even more simple than yours. It can be done in only a couple lines of code!

2 Likes

Maybe try this?

local function onRenderStepped()
    local cameraPosition = workspace.CurrentCamera.CFrame.Position
    local regionSize = Vector3.new(100, 100, 100)
    local regionCenter = cameraPosition

    -- Create a Region3 object
    local region = Region3.new(regionCenter - regionSize / 2, regionCenter + regionSize / 2)

    local mouseTarget = Players.LocalPlayer:GetMouse().Target
    if not (mouseTarget and mouseTarget:IsA("Part") and mouseTarget:HasTag("Interactable")) then
        for _, part in pairs(workspace:FindPartsInRegion3(region, nil, nil)) do
            if part:IsA("Highlight") then
                part.Parent = nil
            end
        end
    end
end

I think you’re right, very cool. Mines is around 10 lines long.