ClickDetector MouseHoverEnter event not working on the first time?

I’m trying to make a functional bookshelf where you can pick out books to read, and I’ve added some visual effects for when you hover over said books, but they seem inconsistent when you first load in… Also, is there any way at all for me to prevent the mouse cursor from flickering upon hovering?

This is how it looks like:

I’ve tried to look this up but there doesn’t seem to be any posts about it, there was one post about the mouse flickering and apparently it has something to do with the server and client taking time to communicate, which I get, but all of this is done on a LocalScript, so there shouldn’t be a delay right?

Here’s my script

runService.PreRender:Connect(function()
	if mouse.Target ~= nil and mouse.Target.Parent.Name == "Book" then
		local targetPart = mouse.Target
		local bookModel = targetPart.Parent
		
		local tweenGoal1 = {
			CFrame = bookModel.PrimaryPart.CFrame * CFrame.new(0,0,1)
		}
		
		local tweenGoal2 = {
			CFrame = bookModel.PrimaryPart.CFrame * CFrame.new(0,0,-1)
		}
		
		bookModel.ClickDetector.MouseHoverEnter:Connect(function()
			local moveForwardTween = tweenService:Create(bookModel.PrimaryPart, hoverEnterTweenInfo, tweenGoal1)
			bookModel.BillboardGui.AuthorText.Text = "Author: " .. bookModel.Author.Value
			bookModel.BillboardGui.TitleText.Text = "Title: " .. bookModel.Title.Value
			bookModel.Highlight.Enabled = true
			bookModel.BillboardGui.Enabled = true
			moveForwardTween:Play()
		end)
		
		bookModel.ClickDetector.MouseHoverLeave:Connect(function()
			local moveBackwardTween = tweenService:Create(bookModel.PrimaryPart, hoverLeaveTweenInfo, tweenGoal2)
			bookModel.Highlight.Enabled = false
			bookModel.BillboardGui.Enabled = false
			moveBackwardTween:Play()
		end)
	end
end)

Technically the mouse is already inside the selection, so MouseHoverEnter would not be triggered, you have to call the function after connecting, plus you are currently connecting the events over and over again, which is bad for performance and causes future problems.

local isConnected = {}
runService.PreRender:Connect(function()
	if mouse.Target and mouse.Target.Parent.Name == "Book" then
		local targetPart = mouse.Target
		local bookModel = targetPart.Parent
		if not bookModel or isConnected[bookModel] then		return		end
		isConnected[bookModel] = true
		
		
		local tweenGoal1 = {
			CFrame = bookModel.PrimaryPart.CFrame * CFrame.new(0,0,1)
		}

		local tweenGoal2 = {
			CFrame = bookModel.PrimaryPart.CFrame * CFrame.new(0,0,-1)
		}
		
		local function EnterUpdate()
			local moveForwardTween = tweenService:Create(bookModel.PrimaryPart, hoverEnterTweenInfo, tweenGoal1)
			bookModel.BillboardGui.AuthorText.Text = "Author: " .. bookModel.Author.Value
			bookModel.BillboardGui.TitleText.Text = "Title: " .. bookModel.Title.Value
			bookModel.Highlight.Enabled = true
			bookModel.BillboardGui.Enabled = true
			moveForwardTween:Play()
		end
		bookModel.ClickDetector.MouseHoverEnter:Connect(EnterUpdate)
		EnterUpdate()

		bookModel.ClickDetector.MouseHoverLeave:Connect(function()
			local moveBackwardTween = tweenService:Create(bookModel.PrimaryPart, hoverLeaveTweenInfo, tweenGoal2)
			bookModel.Highlight.Enabled = false
			bookModel.BillboardGui.Enabled = false
			moveBackwardTween:Play()
		end)
	end
end)
1 Like

That fixed it, but I still wonder why is the mouse considered to “already be inside the selection”?
Because when I start the game my mouse hasn’t hovered over the books yet

Also how can I avoid from connecting events forever if it’s bad?

MouseHoverEnter is activated when the player places the mouse over it, when you detect with RunService, let’s say that the method has already been activated, but you did not connect your function.

Connecting an event forever is not bad, the problem is when you connect something several times: suppose you connect something so that it prints “hello”, if you connect 2 times the method will print “hello” 2 times at the same time.