How can I make a moving gui stop at the center of another one

  1. What do you want to achieve? I’m making an RNG game where a GUI makes a bunch of numbers that scroll past the screen, and then eventually lands on one. I want to make it so that it will always go to the center of the box that it landed on. Basically how it does it in this clip:

  2. What is the issue? I have absolutely no clue how I could even begin with this.

  3. What solutions have you tried so far? None since I don’t really know what to do in the first place.

This is what I have so far:

This is the script that handles the movement of the GUI.

local player = game.Players.LocalPlayer
local auraboxtemplate = script.Box

local ts = game:GetService("TweenService")

local RollUI = player:WaitForChild("PlayerGui").RollUI

local loops = 1

local player = game.Players.LocalPlayer
local auraboxtemplate = script.Box

local ts = game:GetService("TweenService")

local RollUI = player:WaitForChild("PlayerGui").RollUI

local function absolutepos(udim2) -- This isn't being used right now.
	local absoluteSize = game:GetService("Workspace").CurrentCamera.ViewportSize
	local xOffset = udim2.X.Scale * absoluteSize.X
	xOffset += udim2.X.Offset
	local yOffset = udim2.Y.Scale * absoluteSize.Y
	yOffset += udim2.Y.Offset
	return Vector2.new(xOffset, yOffset)
end

script.Parent.Roll.MouseButton1Click:Connect(function()
	script.Parent.Roll.Interactable = false
	local luck = 1
	local base = 0.5
	
	ts:Create(RollUI.BG, TweenInfo.new(1), {BackgroundTransparency = 0.5}):Play()
	
for i = 1, 135, 1 do
	local co = coroutine.create(function()
		for i, v in RollUI.Frame:GetChildren() do
        if v.Name == "Box" then
            v:Destroy()
        end
	end
        local number, name = game.ReplicatedStorage:WaitForChild("Remotes").RollFunction:InvokeServer(luck, base)
        local newBox = auraboxtemplate:Clone()
        newBox.Parent = RollUI.Frame
        local copiedAuraTitle = nil
        local copiedAuraRNG = nil
        for i, v in game.ReplicatedStorage:WaitForChild("AuraTitles").NonSecret:GetChildren() do
            if v.Name == name then
                copiedAuraTitle = v.Aura
                copiedAuraRNG = v.RNG
            end
		end
		
		if copiedAuraTitle ~= nil and copiedAuraRNG ~= nil then
			local newTitle = copiedAuraTitle:Clone()
        	local newRNG = copiedAuraRNG:Clone()

			newTitle.Parent = newBox
			newTitle.Text = name
			newRNG.Parent = newBox
			newRNG.Text = number.." rng"
		else
			local newTitle = game.ReplicatedStorage.AuraTitles.NonSecret.Basic.Aura:Clone()
			local newRNG = game.ReplicatedStorage.AuraTitles.NonSecret.Basic.RNG:Clone()
			
			newTitle.Parent = newBox
			newTitle.Text = "unknown"
			newRNG.Parent = newBox
			newRNG.Text = number.." rng"
		end
	end)
	coroutine.resume(co)
end
task.wait(1)
RollUI.Frame.Visible = true
RollUI.Arrow.Visible = true
print(#RollUI.Frame:GetChildren() - 3)
ts:Create(RollUI.Frame, TweenInfo.new(3, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = UDim2.fromScale(math.random(-15.00, -5.00), 0.323)}):Play()
end)

(By the way, sorry if the title isn’t clear enough, I couldn’t figure out how to word it while keeping it short.)

1 Like

You want to use the absolute position of the chosen label and then tween an additional ammount that is the distance to the center of the X axis of the screen

The middle of the screen should be this:
workspace.CurrentCamera.ViewportSize.X / 2 (we dont want this to be a variable as viewport size can change)

Now take the absolute label position on the X axis as this:
winningLabel.AbsolutePosition.X

Now simply get the difference:
(workspace.CurrentCamera.ViewportSize.X / 2)-winningLabel.AbsolutePosition.X

And adjust the position with maybe another tween

I haven’t made it so it chooses which label got selected. It just moves to a random position along the list of labels, so I’d need to figure out a way to do that first, is there a way I can find which label is under the arrow?

Here is a great resource for that; Creating a Crate/Spin System

I’m confused, I made it so it gives each label an ID and then after they’re all loaded, chooses a random one to be the selected one. I don’t know how I’m supposed to make it go to that one’s position though.

well, all i can tell you is, read the post i linked

The part I don’t understand is the actual getting it to move to the right one. My rolling ui is set up differently, and uses a UIGridLayout to keep all the boxes in a row, and I don’t know if that affects how I have to do it.

In the tutorial there are no layout instances used; you should consider switching your ui, it shouldn’t be that hard.

As you can see, they decided to offset the labels

local crateSizeX = template.AbsoluteSize.X
local crateGapX = 10
local crateTotalGapX = crateSizeX + crateGapX
for i = 1, contents.Crates do
	local crate = template:Clone()
	crate.Name = "Crate"..i
	crate.Position = crate.Position + UDim2.new(0, crateTotalGapX*(i-1), 0, 0)
	crate.Parent = holder
end

firstly determine the size of the label (local crateSizeX = template.AbsoluteSize.X)
and to get the position of the n(th) label you calculate it as (sizeX + gap) * (n-1)
minus 1 so the first label is always in the center of the screen

Now you simply need to pick a random label, make it say whatever you decided to win earlier (check out this post too)
and then animate the scroller to move to the offset that the label is at

I tried the new method for making the grid and it seems to be mostly working but the boxes aren’t scaled correctly on the Y axis now.

I can’t really tell you much without seeing your ui structure

This is the ui in the explorer. Box is the template for the labels, and RollUI.Frame is the main frame that the boxes go into.

image

Well, i suppose change the template size :person_shrugging:
check out the SizeConstraint property too

It’s much closer to what I’m going for now, however it lands a little to the left of the center. This is the script

	local selectedBox = nil
	task.wait(1)
	local SelectedAura = math.random(55, 110)
	for i, v in RollUI.Frame:GetChildren() do
		if v.Name == "Box" then
			print(SelectedAura)
			print(v.ID.Value)
			if v:WaitForChild("ID").Value == SelectedAura then
				selectedBox = v
			end
		end
	end
	local finalPosition = UDim2.fromOffset(-(auraboxtemplate.AbsoluteSize.X + 10) * (selectedBox.ID.Value-1), 183.787)
	RollUI.Frame.Visible = true
	RollUI.Arrow.Visible = true
	ts:Create(RollUI.Frame, TweenInfo.new(3, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out), {Position = finalPosition}):Play()

Where it lands on the box:

Can you show me where you assign the other label’s positions?

also you can swap a part to this:

for _, v in RollUI.Frame:GetChildren() do
	if v.Name == "Box" and v.ID.Value == SelectedAura then
		selectedBox = v
		break
	end
end

These 3 lines make the new labels and give them their positions

	local newBox = auraboxtemplate:Clone()
	newBox.Position = newBox.Position + UDim2.new(0, crateTotalGapX*(i-1), 0, 0)
	newBox.Parent = RollUI.Frame

Okay but can you show me where you assign crateTotalGapX too

I put them near the top of the script so they can be used anywhere.

local crateSizeX = auraboxtemplate.AbsoluteSize.X
local crateGapX = 10
local crateTotalGapX = crateSizeX + crateGapX

Okay, i don’t know then since you do add the gap
Just try playing around with it untill you get someting that works

Found the solution, I had to multiply the crateGapX by 2 when I got the final position for the roller to go to.

local finalPosition = UDim2.fromOffset(-(crateSizeX + crateGapX*2) * (selectedBox.ID.Value-1), 183.787)

Nevermind, that apparently didn’t fix it? It worked the first time but not the second.

It seems to just be extremely inconsistent in general. Sometimes it lands on the far right, sometimes it lands to the left, and sometimes it lands close to the center, which really doesn’t change no matter how I modify the script.

Major update: Apparently it’s actually just not even going to the right box at all, which would explain the inconsistency. I don’t have enough time to finish this today so I’ll come back to it tomorrow.