Highlighting issue

  1. What do you want to achieve? I want to find a way to fix a highlight bug

  2. What is the issue? I have a movement system that works based off tiles and their range, the range is visually shown with highlights, but the highlights show parts that arent in range

  3. What solutions have you tried so far? I’ve asked people I know and look at some highlight bugs in the devforum, but no workarounds I’ve found have worked yet.

Code (client)

local plr = game:GetService("Players").LocalPlayer
local mouse = plr:GetMouse()

local UserInputService = game:GetService("UserInputService")

local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- VARIABLES

local target
local action:string
local standingOn
local class

local map:Model = workspace.MapLoaded:GetChildren()[1]
local tiles:Folder = map.Tiles

-- FUNCTIONS

function renewHighlight(enabled)
	local highlight = Instance.new("Highlight")
	highlight.FillColor = Color3.fromRGB(0, 16, 255)
	highlight.OutlineColor = Color3.fromRGB(106, 144, 237)
	highlight.DepthMode = Enum.HighlightDepthMode.Occluded
	
	if map.Selected:FindFirstChildWhichIsA("Highlight") then
		map.Selected.Highlight.Adornee = nil
		map.Selected.Highlight.Enabled = false
		map.Selected.Highlight:Destroy()
		
		print("this is a print")
	end
	
	highlight.Enabled = enabled
	highlight.Adornee = map.Selected
	highlight.Parent = map.Selected
end

function removeHighlight()
	for i, v in map.Selected:GetChildren() do
		if v:IsA("BasePart") then
			v.Parent = tiles
		end
	end

	action = nil
	class = nil
	renewHighlight(false)
end

function getTileOn(part) --part = target, gets the tile the target is standing on via ray
	local model = part.Parent
	
	local rayParams = RaycastParams.new()
	rayParams.FilterType = Enum.RaycastFilterType.Exclude
	rayParams.FilterDescendantsInstances = model:GetChildren()
	
	local ray = workspace:Raycast(model.HumanoidRootPart.Position, Vector3.new(0, -5, 0), rayParams)
	
	return ray.Instance
end

function highlight(range, option)
	range *= 7.5
	
	for i, v in tiles:GetChildren() do
		standingOn = getTileOn(target)
		
		if (v.Position - standingOn.Position).Magnitude <= range then
			v.Parent = map.Selected
		else
			v.Parent = tiles
		end
	end
	
	renewHighlight(true)
end

--Actual script

UserInputService.InputBegan:Connect(function()
	target = mouse.Target
	if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) and target and target:IsDescendantOf(workspace.Playable) then
		action = "Move"
		class = target.Parent
				
		highlight(8, action) --range here is in tiles
	elseif UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) and target and target:IsDescendantOf(map.Selected) then 
		ReplicatedStorage.Events.ClickEvent:FireServer(class, target)
					
		removeHighlight()
	elseif UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
		removeHighlight()
	end
end)

Video:

Video (shows explorer and explorer interaction):

1 Like

this might be your issue

It all uses one highlight, as the selected parts are groupped

1 Like

@hya123456h , you can see that more than 31 highlights are visible in the video.
But, yes, you shouldn’t use highlights, changing the brickColor, or having a custom highlight model will work.

I looked over the code, and it seems it should work, Why do you *= the range by 7.5?

the tiles are 7 studs in width, its so I can just put the range in tiles when calling the function

I’ve done changing brickcolor but I’d rather have highlights if possible as it just looks better imo

I got it. In the video, the first time you select the troop, the tiles way up at the top are visible, and when you move him, and select him again, you forgot to - reset the original model and remove the highlight from it. So the first model is activating as well, you need to ungroup the model after you move the troop.

I put the tiles that arent in range back in the “Tiles” folder in the highlight function, and if they are in range in the “Selected” model, I may be misreading what you’re saying but it does update whats actually in the model, I show what happens in the explorer here, it also seems to fix itself when selecting the model or a descendant of it in explorer, with the bug continuing after it.

You can also see a similar effect that you see normally if you keep the “Selected” model selected in explorer.


(Take note of how it shows the whole board is in the selected model, but with there only being a highlight in explorer)

Also sorry that my response time took abit

local plr = game:GetService("Players").LocalPlayer
local mouse = plr:GetMouse()

local UserInputService = game:GetService("UserInputService")

local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- VARIABLES

local target
local action:string
local standingOn
local class

local map:Model = workspace.MapLoaded:GetChildren()[1]
local tiles:Folder = map.Tiles

-- FUNCTIONS

function renewHighlight(enabled)
if not map.Selected:FindFirstChildWhichIsA("Highlight") then
	local highlight = Instance.new("Highlight")
	highlight.FillColor = Color3.fromRGB(0, 16, 255)
	highlight.OutlineColor = Color3.fromRGB(106, 144, 237)
	highlight.DepthMode = Enum.HighlightDepthMode.Occluded
	end
local highlight = map.Selected:FindFirstChildWhichIsA("Highlight")
	
	
	highlight.Enabled = enabled
	highlight.Adornee = map.Selected
	highlight.Parent = map.Selected
end

function removeHighlight()
	for i, v in map.Selected:GetChildren() do
		if v:IsA("BasePart") then
			v.Parent = tiles
		end
	end

	action = nil
	class = nil
	renewHighlight(false)
end

function getTileOn(part) --part = target, gets the tile the target is standing on via ray
	local model = part.Parent
	
	local rayParams = RaycastParams.new()
	rayParams.FilterType = Enum.RaycastFilterType.Exclude
	rayParams.FilterDescendantsInstances = model:GetChildren()
	
	local ray = workspace:Raycast(model.HumanoidRootPart.Position, Vector3.new(0, -5, 0), rayParams)
	
	return ray.Instance
end

function highlight(range, option)
	range *= 7.5
	
	for i, v in tiles:GetChildren() do
		standingOn = getTileOn(target)
		
		if (v.Position - standingOn.Position).Magnitude <= range then
			v.Parent = map.Selected
	end
	
	renewHighlight(true)
end

--Actual script

UserInputService.InputBegan:Connect(function()
	target = mouse.Target
	if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) and target and target:IsDescendantOf(workspace.Playable) then
		action = "Move"
		class = target.Parent
				
		highlight(8, action) --range here is in tiles
	elseif UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) and target and target:IsDescendantOf(map.Selected) then 
		ReplicatedStorage.Events.ClickEvent:FireServer(class, target)
					
		removeHighlight()
	elseif UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
		removeHighlight()
	end
end)

see if this works.

Normal gameplay:

When selected in the explorer:

How about instead of resetting the tiles when you click, once your NPC stops moving, you rest it by default?

It does this when it starts moving with removeHighlight() being called when it checks that what you clicked on is a descendant of “Selected”, I did put an event the fires on the server (as theres where the pathfinding takes place) that connects to the removeHighlight function for cilent when the path is finished just for testing purposes, same result

Clearly the tiles aren’t being cleared after each movement.

From the first video, you can see that on the second movements, the first set of tiles are highlighted. Just clear any tables containing tiles before moving again.

I see the pattern, but in the vid where I show whats going on in the workspace shows that it is infact being cleared, it even fixes itself when the model is selected in explorer

Multiplying by 7.5 is the issue as you said yourself the tiles are just 7 studs in width.

the point of the .5 is because the range starts from the tiles (the one it’s standing on) center, which is half of it’s width (setting to just 7 would only be 7 tiles out instead of my wanted 8)

but the multiplication wouldn’t cause a bug like this, even if a set it to 60 manually (8 * 7.5) it does this

It’s important to make sure the server and client range code is the same.

0.5 is also not half of a tile’s width if the width is 7, 3.5 is – besides this shouldn’t be relevant because you’re checking the distance from one tile center to another tile center.

If you want to add a threshold to counter floating point issues, then simply add 0.1 or some other number to the range – not multiply.

Theres no range for the server, server only handles the pathfind, and I’m not sure if editing the range value necessarily fixes this as it seems to have a pattern “saving” what the model had previously, despite the model not actually doing so

If what I said didn’t fix the issue, then a workaround I’ve used before to force a highlight to update is to disable and enable the highlight instance. Although, keep in mind this is quite performance intensive depending on how many items need to be rendered in the highlight.

Hey there, is it possible that your adornee for the highlight is set to “nil”/unset? If so, please consider changing it to the model which has the tiles you want to highlight and let me know if that fixed the issue.

I set it to “map.Selected” in renewHighlight()