Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

MouseLeave not working when mouse moves fast? How to fix?

Asked by 5 years ago

I'm making a button where you hover over the button and something tweens out a description with MouseEnter. When I want it to tween back in, I would use MouseLeave. It works well but, when you move your mouse fast over the button, it will not fire the event, therefore the description is now stuck on the screen. If anyone knows how to fix or work around this, please let me know! I'm guessing there is a way with InputService but I am not sure how to do it. Any help will be appreciated!

1 answer

Log in to vote
0
Answered by 5 years ago

If you're really struggling with this, I made a very messy module (must be created as ModuleScript and placed on the client).

local Mouse = require(script.Parent.Module) -- Path to the ModuleScript
local button = script.Parent;

local ButtonEvent = Mouse:new(button);


-- Fires once mouse has left the button
ButtonEvent:MouseLeave(function()
    print'left'
end)

-- Fires once mouse has entered the button
ButtonEvent:MouseEnter(function()
    print'entered'
end)

-- Once you don't want to listen to it anymore
ButtonEvent:destroy();

Note that this binds itself to RenderStepped.

Module code:

local RunService = game:GetService("RunService")
local HttpService = game:GetService("HttpService")
repeat wait() until game.Players.LocalPlayer
local Player = game.Players.LocalPlayer
local mouse = Player:GetMouse()


function collides(gui1, gui2)
    local g1p, g1s = gui1.AbsolutePosition, gui1.AbsoluteSize;
    local g2p, g2s = gui2.AbsolutePosition, gui2.AbsoluteSize;
    return ((g1p.x < g2p.x + g2s.x and g1p.x + g1s.x > g2p.x) and (g1p.y > g2p.y and g1p.y < g2p.y + g2s.y)) 
    or ((g2p.x < g1p.x + g1s.x and g2p.x + g2s.x > g1p.x) and (g2p.y > g1p.y and g2p.y < g1p.y + g1s.y));
end;


local followGui = Instance.new("ScreenGui")
followGui.Parent = Player:WaitForChild("PlayerGui");
followGui.Name = "MouseFollowGui"
followGui.ResetOnSpawn = false
local followFrame = Instance.new("Frame");
followFrame.Size = UDim2.new(0,1,0,1)
followFrame.Parent = followGui

mouse.Move:Connect(function()
    followFrame.Position = UDim2.new(0, mouse.X, 0, mouse.Y)
end)


local mouseObj = {
    isActive = true,
    binded = nil,
    lastState = false,
    mouseEnters = {},
    mouseLeaves = {}
}

function fireCallbacks (tab, ...)
    for i,v in pairs(tab) do
        v(...)
    end
end

function mouseObj:destroy()
    self.isActive = false
    RunService:UnbindFromRenderStep(self.binded)
    return true
end

function mouseObj:new (obj)
    if not obj:IsA("GuiObject") then return error("Not a valid GuiObject") end

    local newMouse = {};
    setmetatable(newMouse, self)
    self.__index = self;

    self.binded = HttpService:GenerateGUID(false)

    RunService:BindToRenderStep(self.binded, Enum.RenderPriority.Last.Value, function()
        local doesCollide = collides(followFrame, obj)
        if self.lastState == false and doesCollide then
            self.lastState = true
            fireCallbacks(self.mouseEnters)
        elseif self.lastState == true and not doesCollide then
            self.lastState = false
            fireCallbacks(self.mouseLeaves)
        end
    end)

    return newMouse;
end

function mouseObj:MouseEnter(cb)
    if type(cb) ~= "function" then return error("Not a valid callback parameter") end
    table.insert(self.mouseEnters, cb)
end

function mouseObj:MouseLeave(cb)
    if type(cb) ~= "function" then return error("Not a valid callback parameter") end
    table.insert(self.mouseLeaves, cb)
end



return mouseObj;
Ad

Answer this question