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)
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.