Highlighting objects with your mouse

Hi! I recently heard that aren’t any tutorials on devforum that would show you how to make a script that can highlight objectives when you point your mouse towards them. The system uses custom highlights.

To understand what this means, I brought an image for you:

Video about it:

(Sorry for not seeing the mouse on this pic btw)

So how to make it - The first 2 parts are about how to make it and why to make it, the 3rd part will have the script itself

How to make it

I. - Setting up the Studio

  • Go to the Explorer, click on the StarterPlayer object, then into StarterCharacterScripts insance a localscript. image

  • Place down a part, and instance a Highlight into it

II. - The scripting

So to understand how this works, open the localscript first. We want to use the mouse for this and some highlights too. We want to reach the exact target of the mouse, so we will use:

game.Players.LocalPlayer:GetMouse().Target

We also want to check the parts every single moment, this is why we are going to use Runservice.
The system will select a part if the part if:

  • Has a highlight

The system will interact with a part if:

  • The part has a highlight
  • The script already interacted with a highlight
  • The highlight is changed

These are the things we want to achive.

We can already write these lines of the code

`game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local highlight = target:FindFirstChild("Highlight")`

To make sure the script will be able to interact with highlights that the script is not interacting at the moment, we need an objectvalue.
An objectvalue works like a simple value, expect its value is an object from the explorer. However, there could be a situation where this value is nil (at the start).

When we have the highlight, we can just write this code:

local value = Instance.new("ObjectValue")
local valueHL = Instance.new("ObjectValue")

game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local highlight = target:FindFirstChild("Highlight")
		if highlight then
			value.Parent = highlight
			value.Value = highlight
			target.Highlight.Enabled = true

But there can be a situation, where we move our cursor from a highligh-contained part onto another highlight-contained part. This is the point where we need a 2nd objectvalue, and the reason we need to do it a bit more complex.

We have to check if the current target is the same with the value, or it’s different.
→ If it’s different, we selected a new part, so the old part should be not highlighted
→ if it’s the same, there is nothing to do with, the part should be highlighted

if value.Value ~= valueHL.Value then
				if valueHL.Value ~= nil then --At this point we check if the value has a part in it, otherwise it would glitch
					valueHL.Value.Enabled = false --At this point we set off the old highlight
				end
			end

But if we move our cursor onto a not-highlight part, the highlight should not be enabled, so the last part (the current value of the first objectvalue) will call that part and set its light to false.

if not highlight then
			if value.Value ~= nil then
				value.Value.Enabled = false
			end
		end

The ‘local value’ will always be the current targeted part, the valueHL will be the last selected part.

if highlight then
			value.Parent = highlight
			value.Value = highlight --At this point, we set the part as the new value, the valueHL will be the previous part, because we set the valueHL to the new part just later in this script
			target.Highlight.Enabled = true
			if value.Value ~= valueHL.Value then --So at this point valueHL is the older part, because we didn't set it to the new part yet, like 2 lines under, and now the 2 values have 2 different objects, and we check if they changed
				if valueHL.Value ~= nil then --If the value has an object in it, then it will go forward, else if the value is nil, it can't be set to true or it will glitch the script
					valueHL.Value.Enabled = false
				end
			end
			valueHL.Parent = highlight --And now we can set the valueHL to the current part, then the script will recheck itself because of the runservice
			valueHL.Value = highlight
		end
if not highlight then --If the cursor is on a part that has no highlight then the current part(the value always changes when the highlight is true) will be set the false because it wasn't changed
			if value.Value ~= nil then
				value.Value.Enabled = false
			end
		end

The W h o l e script:

local value = Instance.new("ObjectValue")
local valueHL = Instance.new("ObjectValue")

game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local highlight = target:FindFirstChild("Highlight")
		if highlight then
			value.Parent = highlight
			value.Value = highlight
			target.Highlight.Enabled = true
			if value.Value ~= valueHL.Value then
				if valueHL.Value ~= nil then
					valueHL.Value.Enabled = false
				end
			end
			valueHL.Parent = highlight
			valueHL.Value = highlight
		end
		if not highlight then
			if value.Value ~= nil then
				value.Value.Enabled = false
			end
		end
	end
end)

Let’s say you wanna make it so in an area you want to select the highlight things. It’s okay, we check if the target is true (not the sky) and if our head and the part is in an area.
In this case, we check a magnitude between the 2 parts, and the others are kept. Feel free to edit the distance

local value = Instance.new("ObjectValue")
local valueHL = Instance.new("ObjectValue")
local playerPos = game.Players.LocalPlayer.Character:FindFirstChild("Head").Position

game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local partPos = target.Position
		if (playerPos-partPos).Magnitude < 100 then --Distance. If you want to edit the distance, change the number 100 to anything you would like to.
			if target then
				local highlight = target:FindFirstChild("Highlight")
				if highlight then
					value.Parent = highlight
					value.Value = highlight
					target.Highlight.Enabled = true
					if value.Value ~= valueHL.Value then
						if valueHL.Value ~= nil then
							valueHL.Value.Enabled = false
						end
					end
					valueHL.Parent = highlight
					valueHL.Value = highlight
				end
				if not highlight then
					if value.Value ~= nil then
						value.Value.Enabled = false
					end
				end
				target.Changed:Connect(function()
				end)
			end
		end
	end
end)

Hope you understood it and learned something new today, or earned a new feature that you can use in your game.
Of course you can modify the script if you want to check about different types of highlights or etc, it’s a basic but good version of it. Feel free to use it.

III. - The scripts:

Without Magnitude:

local value = Instance.new("ObjectValue")
local valueHL = Instance.new("ObjectValue")

game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local highlight = target:FindFirstChild("Highlight")
		if highlight then
			value.Parent = highlight
			value.Value = highlight
			target.Highlight.Enabled = true
			if value.Value ~= valueHL.Value then
				if valueHL.Value ~= nil then
					valueHL.Value.Enabled = false
				end
			end
			valueHL.Parent = highlight
			valueHL.Value = highlight
		end
		if not highlight then
			if value.Value ~= nil then
				value.Value.Enabled = false
			end
		end
	end
end)

With Magnitude:

local value = Instance.new("ObjectValue")
local valueHL = Instance.new("ObjectValue")
local playerPos = game.Players.LocalPlayer.Character:FindFirstChild("Head").Position

game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local partPos = target.Position
		if (playerPos-partPos).Magnitude < 100 then
			if target then
				local highlight = target:FindFirstChild("Highlight")
				if highlight then
					value.Parent = highlight
					value.Value = highlight
					target.Highlight.Enabled = true
					if value.Value ~= valueHL.Value then
						if valueHL.Value ~= nil then
							valueHL.Value.Enabled = false
						end
					end
					valueHL.Parent = highlight
					valueHL.Value = highlight
				end
				if not highlight then
					if value.Value ~= nil then
						value.Value.Enabled = false
					end
				end
				target.Changed:Connect(function()
				end)
			end
		end
	end
end)

If you want to make sure this system will never glitch, use this code, where the script will instance highlights if the target has a specific value:

local value = Instance.new("ObjectValue")
local valueHL = Instance.new("ObjectValue")

game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local highlight = target:FindFirstChild("HighlightValue")
		local hlObject = Instance.new("Highlight")
		if highlight then
			if highlight.Value == true then
				hlObject.Parent = target
				value.Parent = script
				value.Value = hlObject
				if value.Value ~= valueHL.Value then
					if valueHL.Value ~= nil then
						valueHL.Value:Destroy()
					end
				end
				valueHL.Parent = script
				valueHL.Value = hlObject
			end
		end
		if not highlight then
			if value.Value ~= nil then
				value.Value:Destroy()
			end
			if valueHL.Value ~= nil then
				valueHL.Value:Destroy()
			end
		end
		if not target then
			if value.Value ~= nil then
				value.Value:Destroy()
			end
			if valueHL.Value ~= nil then
				valueHL.Value:Destroy()
			end
		end
	end
end)

Feel free to use it anywhere

If you have any question about it, write a comment.

19 Likes

This script relies on the highlight instances already being present in parts.

Why is this bad? Highlights have a limit of 31 existing at once. You might think that this is fine, but highlights that are not enabled still count to the limit. So with this method, you can only have a maximum of 31 object that you can highlight with your mouse.

4 Likes

Yeah, agreed. I would just check if the player is hovering over a object and if it is, the script will insert a highlight instance into it. When the player is not hovering over the object anymore, the highlight instance will be removed/destroyed.

2 Likes

You can make it with a simple value too, check if the part has a special value in it, and if yes, you can just instance one into it. Also you can script it into it at any time, it’s not that hard, it’s a simple version of it.

2 Likes

Because the Roblox methods won’t prefer infinity highlights, here’s a fixed version of the code, where it instances a highlight if the target has a specific value.

local value = Instance.new("ObjectValue")
local valueHL = Instance.new("ObjectValue")

game:GetService("RunService").RenderStepped:Connect(function()
	local target = game.Players.LocalPlayer:GetMouse().Target
	if target then
		local highlight = target:FindFirstChild("HighlightValue")
		local hlObject = Instance.new("Highlight")
		if highlight then
			if highlight.Value == true then
				hlObject.Parent = target
				value.Parent = script
				value.Value = hlObject
				if value.Value ~= valueHL.Value then
					if valueHL.Value ~= nil then
						valueHL.Value:Destroy()
					end
				end
				valueHL.Parent = script
				valueHL.Value = hlObject
			end
		end
		if not highlight then
			if value.Value ~= nil then
				value.Value:Destroy()
			end
			if valueHL.Value ~= nil then
				valueHL.Value:Destroy()
			end
		end
		if not target then
			if value.Value ~= nil then
				value.Value:Destroy()
			end
			if valueHL.Value ~= nil then
				valueHL.Value:Destroy()
			end
		end
	end
end)
1 Like

You wanted to say “just”? Also I like this tutorial I think it’ll help a lot!