How to fix this?

So, there’s a problem, I have a script which outlines something on hover. I made smooth fade in and out, but there is a problem because the mouse needs to detect “empty space” before the unhover effect is triggered.

Going from Rig to Rig without touching any empty space, will lead to this and I want to fix this.

Code:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")

local HIGHLIGHT_TAG = "Highlightable"
local FADE_OUT_TIME = 0.3
local MAX_DISTANCE = 25
local TARGET_FILL_TRANSPARENCY = 0.8
local TARGET_OUTLINE_TRANSPARENCY = 0

local highlightTemplate = script.Highlight
local currentHighlights = {}

local function withinActivationDistance(target)
	local character = player.Character
	if not character or not character:FindFirstChild("HumanoidRootPart") then
		return false
	end
	local rootPart = character.HumanoidRootPart
	local targetPosition = target.Position
	return (rootPart.Position - targetPosition).Magnitude <= MAX_DISTANCE
end

local function createFadeInTween(highlight)
	local outlineTweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	local fillTweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)

	local outlineTween = TweenService:Create(highlight, outlineTweenInfo, {
		OutlineTransparency = TARGET_OUTLINE_TRANSPARENCY,
	})

	local fillTween = TweenService:Create(highlight, fillTweenInfo, {
		FillTransparency = TARGET_FILL_TRANSPARENCY,
	})

	return outlineTween, fillTween
end

local function createFadeOutTween(highlight)
	local tweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	return TweenService:Create(highlight, tweenInfo, {
		FillTransparency = 1,
		OutlineTransparency = 1
	})
end

local function highlightObject(target)
	if currentHighlights[target] then
		return  -- Already highlighted, do nothing
	end

	local highlight = highlightTemplate:Clone()
	highlight.Parent = game.Workspace  -- Adjust parent as necessary

	local outlineTween, fillTween = createFadeInTween(highlight)

	currentHighlights[target] = {
		Highlight = highlight,
		OutlineTween = outlineTween,
		FillTween = fillTween,
		FadingOut = false  -- Remove FadeOutTween and use FadingOut flag
	}

	outlineTween:Play()
	fillTween:Play()
	highlight.Adornee = target
end

local function fadeOutHighlight(target)
	local highlightData = currentHighlights[target]
	if not highlightData or highlightData.FadingOut then
		return
	end

	highlightData.FadingOut = true
	local fadeOutTween = createFadeOutTween(highlightData.Highlight)
	fadeOutTween:Play()
	fadeOutTween.Completed:Connect(function()
		highlightData.Highlight.Adornee = nil
		highlightData.Highlight:Destroy()
		currentHighlights[target] = nil
	end)
end

mouse.Move:Connect(function()
	local target = mouse.Target

	-- Check if the mouse is over a highlightable object within activation distance
	if target and withinActivationDistance(target) then
		if CollectionService:HasTag(target, HIGHLIGHT_TAG) then
			if not currentHighlights[target] then
				highlightObject(target)
			end
		elseif target.Parent and CollectionService:HasTag(target.Parent, HIGHLIGHT_TAG) then
			if not currentHighlights[target.Parent] then
				highlightObject(target.Parent)
			end
		end
	else
		-- Mouse is not over a valid highlightable object, fade out all highlights
		for target, highlightData in pairs(currentHighlights) do
			fadeOutHighlight(target)
		end
	end
end)

Video:

1 Like

I’ve managed to fix it.

Script:

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")

local HIGHLIGHT_TAG = "Highlightable"
local FADE_OUT_TIME = 0.3
local MAX_DISTANCE = 25
local TARGET_FILL_TRANSPARENCY = 0.8
local TARGET_OUTLINE_TRANSPARENCY = 0

local highlightTemplate = script.Highlight
local currentHighlights = {}

local function withinActivationDistance(target)
	local character = player.Character
	if not character or not character:FindFirstChild("HumanoidRootPart") then
		return false
	end
	local rootPart = character.HumanoidRootPart
	local targetPosition = target.Position
	return (rootPart.Position - targetPosition).Magnitude <= MAX_DISTANCE
end

local function createFadeInTween(highlight)
	local outlineTweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	local fillTweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)

	local outlineTween = TweenService:Create(highlight, outlineTweenInfo, {
		OutlineTransparency = TARGET_OUTLINE_TRANSPARENCY,
	})

	local fillTween = TweenService:Create(highlight, fillTweenInfo, {
		FillTransparency = TARGET_FILL_TRANSPARENCY,
	})

	return outlineTween, fillTween
end

local function createFadeOutTween(highlight)
	local tweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	return TweenService:Create(highlight, tweenInfo, {
		FillTransparency = 1,
		OutlineTransparency = 1
	})
end

local function highlightObject(target)
	if currentHighlights[target] then
		return  -- Already highlighted, do nothing
	end

	local highlight = highlightTemplate:Clone()
	highlight.Parent = game.Workspace  -- Adjust parent as necessary

	local outlineTween, fillTween = createFadeInTween(highlight)

	currentHighlights[target] = {
		Highlight = highlight,
		OutlineTween = outlineTween,
		FillTween = fillTween,
		FadingOut = false  -- Remove FadeOutTween and use FadingOut flag
	}

	outlineTween:Play()
	fillTween:Play()
	highlight.Adornee = target
end

local function fadeOutHighlight(target)
	local highlightData = currentHighlights[target]
	if not highlightData or highlightData.FadingOut then
		return
	end

	highlightData.FadingOut = true
	local fadeOutTween = createFadeOutTween(highlightData.Highlight)
	fadeOutTween:Play()
	fadeOutTween.Completed:Connect(function()
		highlightData.Highlight.Adornee = nil
		highlightData.Highlight:Destroy()
		currentHighlights[target] = nil
	end)
end

mouse.Move:Connect(function()
	local target = mouse.Target
	local foundHighlightable = false

	-- Check if the mouse is over a highlightable object within activation distance
	for highlightedTarget, highlightData in pairs(currentHighlights) do
		if target and (target == highlightedTarget or target:IsDescendantOf(highlightedTarget)) then
			foundHighlightable = true
		else
			fadeOutHighlight(highlightedTarget)
		end
	end

	if target and not foundHighlightable and withinActivationDistance(target) then
		if CollectionService:HasTag(target, HIGHLIGHT_TAG) then
			if not currentHighlights[target] then
				highlightObject(target)
			end
		elseif target.Parent and CollectionService:HasTag(target.Parent, HIGHLIGHT_TAG) then
			if not currentHighlights[target.Parent] then
				highlightObject(target.Parent)
			end
		end
	end
end)

But the game still lags when I move my mouse around the rigs.

Just make it so only rig can be hovered at one time with a variable.

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local CollectionService = game:GetService("CollectionService")
local TweenService = game:GetService("TweenService")

local HIGHLIGHT_TAG = "Highlightable"
local FADE_OUT_TIME = 0.3
local MAX_DISTANCE = 25
local TARGET_FILL_TRANSPARENCY = 0.8
local TARGET_OUTLINE_TRANSPARENCY = 0

local highlightTemplate = script.Highlight
local currentHighlight = nil :: Instance?

local function withinActivationDistance(target)
	local character = player.Character
	if not character or not character:FindFirstChild("HumanoidRootPart") then
		return false
	end
	local rootPart = character.HumanoidRootPart
	local targetPosition = target.Position
	return (rootPart.Position - targetPosition).Magnitude <= MAX_DISTANCE
end

local function createFadeInTween(highlight)
	local outlineTweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	local fillTweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)

	local outlineTween = TweenService:Create(highlight, outlineTweenInfo, {
		OutlineTransparency = TARGET_OUTLINE_TRANSPARENCY,
	})

	local fillTween = TweenService:Create(highlight, fillTweenInfo, {
		FillTransparency = TARGET_FILL_TRANSPARENCY,
	})

	return outlineTween, fillTween
end

local function createFadeOutTween(highlight)
	local tweenInfo = TweenInfo.new(FADE_OUT_TIME, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
	return TweenService:Create(highlight, tweenInfo, {
		FillTransparency = 1,
		OutlineTransparency = 1
	})
end

local function highlightObject(target)
	if currentHighlight and currentHighlight:IsDescendantOf(target) then
		return  -- Already highlighted, do nothing
	end

	local highlight = highlightTemplate:Clone()
	highlight.Parent = target

    currentHighlight = highlight

	local outlineTween, fillTween = createFadeInTween(highlight)

	outlineTween:Play()
	fillTween:Play()
	highlight.Adornee = target
end

local function fadeOutHighlight(target)
	if not currentHighlight or currentHighlight:HasTag("FadingOut") then
		return
	end

    currentHighlight:AddTag("FadingOut")

	local fadeOutTween = createFadeOutTween(currentHighlight)
	fadeOutTween:Play()
	fadeOutTween.Completed:Connect(function()
		currentHighlight.Adornee = nil
		currentHighlight:Destroy()
		currentHighlight = nil
	end)
end

mouse.Move:Connect(function()
	local target = mouse.Target

	-- Check if the mouse is over a highlightable object within activation distance
	if target and withinActivationDistance(target) then
		if CollectionService:HasTag(target, HIGHLIGHT_TAG) then
            highlightObject(target)
		elseif target.Parent and CollectionService:HasTag(target.Parent, HIGHLIGHT_TAG) then
            highlightObject(target.Parent)
		end
	else
		-- Mouse is not over a valid highlightable object, fade out all highlights
        fadeOutHighlight(currentHighlight)
	end
end)