Need help on Selecting a UI and Deselecting (Tween)

So i was trying to make that when your mouse enters the ui it gets “highlighted”, basically it gets like it is about to be selected, the thing is that when you exit your mouse 0.2 seconds (during the task.wait) before it has completed the animation, it kinda breaks because the UI remain in the same position as the TweenPosition stuff, tried to do stuff but it didn’t work

local plr = game:GetService("Players").LocalPlayer
local char = plr.Character or plr.CharacterAdded:Wait()

local UIS = game:GetService('UserInputService')

local screenGui = script.Parent
local main = screenGui.Main
local Background = main.Background
local CharacterStatsUIFolder = Background.CharacterStatsUIFolder
local ModsSelectFolder = Background.ModsSelectFolder

local MainSelectMod = ModsSelectFolder.Selection.Main

local oldZIndex = {
	[1] = 1,
	[2] = 2,
	[3] = 3,
	[4] = 2,
	[5] = 1
}

local oldPosition = {
	[1] = UDim2.new(0.25, 0, 1.156, 0)
}

local oldRotation = {
	[1] = -10
}

local selected = 0

MainSelectMod.ModSelect1.MouseMoved:Connect(function()
	if selected == 0 then
		MainSelectMod.ModSelect1.ZIndex = 10
		MainSelectMod.ModSelect1:TweenPosition(UDim2.new(0.244, 0, 1, 0), Enum.EasingDirection.In, Enum.EasingStyle.Linear, 0.2, false)
		task.wait(0.2)
		print("Selected")
		MainSelectMod.ModSelect1.Rotation = 0
		selected = 1
	end
end)

MainSelectMod.ModSelect1.MouseLeave:Connect(function()
	if selected == 1 then
		MainSelectMod.ModSelect1.ZIndex = oldZIndex[1]
		MainSelectMod.ModSelect1:TweenPosition(oldPosition[1], Enum.EasingDirection.In, Enum.EasingStyle.Linear, 0.2, false)
		task.wait(0.2)
		print("Deselected")
		MainSelectMod.ModSelect1.Rotation = oldRotation[1]
		selected = 0
	end
end)

Removing the task.wait() will make that if the player finds a precise point, the mousemoved event gets activated while the mouseleave event gets activated too, making the two animations play at the same time and make it look weird

2 Likes

why are you using a mouse moved event?? there is an event called mouse enter. Usually mouse enter and mouse leave is paired up together to make a highlight/hover effect for a UI. If you had a different plan for the UI effect, please explain it better. Thanks!

Also regards your script, it could be made much better… See you are using alot of tables as well as unnecessary values which could be using up alot of memory of the Client. If you could show your UI then I would be able to rewrite the code to make it more efficient!

I am using tables to save stuff for later, and im using a mouseMoved event cause it’s like a card selection, making it mouseEnter it will somewhat glitch and not update dynamically, mouseMoved makes it check if there is already a selected card, the original code includes 4 more stuff, if you can make it more efficient i would be happy

the thing that needs to be updated is the “Cards” that are in the mid, they are image label (except the name and stuff on it)

and if possible i want to understand how to make it efficient and less heavy for the client since im kinda new, recently i got into “advanced” stuff

1 Like

could you show me a video of the current working of your project so that I can visualize a better idea?

1 Like

Sure

1 Like

Ok ill try replicating a prototype on my end and give you a result

1 Like

Sorry for the late response, did you mean something like this?

The script is pretty basic:

local TweenService = game:GetService("TweenService")

local Cards = script.Parent

local Data = {}

for _, v:Frame in Cards:GetChildren() do -- Loops through the Children of the Parent folder
	
	if not v:IsA("Frame") then continue end -- Rejects any other type of Instance except Frame
	
	Data[v] = {['Pos'] = v.Position, ['Rot'] = v.Rotation} -- Sets a Dictionary containing all the properties necessary
	
	v.MouseEnter:Connect(function()
		TweenService:Create(v, TweenInfo.new(1), {Position = UDim2.new(v.Position.X.Scale,0,0.95,0)}):Play()
		TweenService:Create(v, TweenInfo.new(1), {Rotation = 0}):Play()
	end) -- Using tweens here
	
	v.MouseLeave:Connect(function()
		task.wait(0.2) -- Specified Delay
		TweenService:Create(v, TweenInfo.new(1), {Position = Data[v]["Pos"]}):Play()
		TweenService:Create(v, TweenInfo.new(1), {Rotation = Data[v]["Rot"]}):Play()
	end)
end

image
You can use these as for reference, and as i mentioned earlier your use of mousemoved is not really reliable in this case, almost every developer uses mouse entered and mouse leave events to make a hover/selection system. Anyways if you want a different style then I can help with you on that.

Side node: Forgot to add that ZIndex, Just make the Frames to 10 in mouse enter and back to its previous.

1 Like

yea, that is what i was looking for

oh yeah, i know this is out of the request of the topic but can you atleast explain me how to make codes efficient / not laggy?

And tbh, That sort of loop is pretty different than the one i am used with pairs(), how does that work and when is it needed mostly?

uh i found a “bug” last minute, this one:

image
Basically it rises 2 cards (due to them being close)

how can i fix it?

Is the ‘Active’ property of the Frame set to true? If not, changing it will make the Card with the higher ZIndex sink input to GuiObjects underneath.

1 Like

They are not “Active”, they have “Interactable” turned on

it’s like the mouseEnter thing ignores the fact that it has another UI in front of it

Also, if the OP decides to use this code excerpt, I wrote an optimized version.

--!strict
local CARD_TAG = "Card"

local TWEEN_TIME = 1
local TWEEN_STYLE = Enum.EasingStyle.Quad
local TWEEN_DIRECTION = Enum.EasingDirection.InOut

local TweenService = game:GetService("TweenService")

local Cards = script.Parent

for _, object: GuiObject in Cards:GetChildren() do
	-- Use Tags instead of ClassName to assign specific GuiObjects as interactable Cards.
	-- Add the CARD_TAG defined at Line 2 to your Cards in the Explorer.
	if not object:HasTag(CARD_TAG) then
		continue
	end

	local tween = TweenService:Create(object, TweenInfo.new(TWEEN_TIME, TWEEN_STYLE, TWEEN_DIRECTION), 
		{Position = UDim2.new(object.Position.X.Scale, 0, 0.95, 0), Rotation = 0}
	)

	object.MouseEnter:Connect(function()
		tween:Play()
	end)

	local tween = TweenService:Create(object, TweenInfo.new(TWEEN_TIME, TWEEN_STYLE, TWEEN_DIRECTION, 0, false, 1), 
		{Position = object.Position, Rotation = object.Rotation}
	)

	object.MouseLeave:Connect(function()
		tween:Play()
	end)
end
1 Like

Try enabling the ‘Active’ property on all the Card Frames. This property prevents GuiObjects like Frames from registering mouse input underneath, which seems to be the issue here.

1 Like

The main problem is… im not using Frames, im using image labels
image
unless i can try turning on Active on the main thing

ImageLabels inherit from GuiObjects, so they have the properties that Frames have.

(edit: I recommend checking out the documentation for GuiObjects so you can get familiar with all the members it contains: GuiObject | Documentation - Roblox Creator Hub)

1 Like

Tried enabling imageLabels “Active” propriety but it didn’t change, tried switching to frames and enabling them but it didn’t work either

Well, that’s strange. If BasePlayerGui.GetGuiObjectsAtPosition allowed you to filter GuiObjects you could probably use it but unfortunately it doesn’t. I’m unsure what to do besides perhaps using invisible GuiObjects that don’t move or overlap as a ‘hitbox.’

1 Like