So for context, our game’s main UI is in a UIPageLayout. We have a top bar that users can tap/click/use controller input to switch. Tap and clicking the button works as expected, the gamepad can select buttons or use L1 or R1 to proceed to the previous and next page respectively.
For some reason, when a new UI appears on screen, the controller input freaks out and puts me on a random page, I’m not pressing L1 or R1, Gamepad, Touch, and ScrollWheelInput are all false so it shouldn’t be scrolling, right? Does anyone have any ideas why this is happening and/or how to fix?
As you can see in this video, I bought a crate and it freaked out and put me on the Equip page. Then, when I pressed claim, it put me on the teleports page? You can tell I don’t intend to do this as the highlight thing at the top doesn’t move.
Binds are created in the InputManager module which is basically a UserInput/ContextActionService wrapper that ensures inputs are valid and whatnot. I’m just completely lost. I’ve added a print inside of the function that switches which page the user is on and nothing.
Relevant parts from the TopBarSwitcher script:
function module:Focus(nameToFocus: string)
if nameToFocus == self.SelectedName then
return
end
print('switching page') -- only prints when I expect it to again
local frameInfo = assert(self._buttons[nameToFocus])
self.SelectedName = nameToFocus
self.SelectionChanged:Fire(nameToFocus)
dropdownMenu.CollapseEvent:Fire();
(self._uiPageLayout :: UIPageLayout):JumpTo(frameInfo.Frame)
tweenService:Create(
self._highlight,
TweenInfo.new(self._uiPageLayout.TweenTime, self._uiPageLayout.EasingStyle, self._uiPageLayout.EasingDirection),
getHighlightPositionAndSize(frameInfo.Button)
):Play()
end
function module:CreateBinds()
self = self :: TopBarSwitcher
framework.inputManager:BindAction('TopBarSwitcherKeybind', function(name, state, inputObject)
if state ~= Enum.UserInputState.Begin then
return
end
print('switching?') -- prints only when I expect it to
if inputObject.KeyCode == Enum.KeyCode.ButtonL1 then
self._uiPageLayout:Previous()
self:Focus(self._uiPageLayout.CurrentPage.Name)
elseif inputObject.KeyCode == Enum.KeyCode.ButtonR1 then
self._uiPageLayout:Next()
self:Focus(self._uiPageLayout.CurrentPage.Name)
end
return Enum.ContextActionResult.Sink
end, { Enum.KeyCode.ButtonL1, Enum.KeyCode.ButtonR1 })
end
To create a crate spinner UI:
function module:CreateCrateSpinner(crateInfo: { CrateGUID: string; ActualObject: string; Coins: number?; DecoyObjects: {string}; Dupe: boolean? }, crateType: string, backgroundColour: Color3)
print(crateInfo)
local newCrate = openingCrate:Clone()
local itemsContainer = newCrate:WaitForChild('Items')
local clipBounds = itemsContainer:WaitForChild('ScrollingFrame'):WaitForChild('ClipBounds')
local uiPageLayout = clipBounds:WaitForChild('UIPageLayout')
local realItemData = framework.itemData.Halos[crateInfo.ActualObject] or framework.itemData.Trails[crateInfo.ActualObject] or framework.itemData['Particle Effects'][crateInfo.ActualObject]
local newLabel = createItemLabel(realItemData) -- function that creates a frame for the cosmetic that should be shown in the spinner
newLabel.LayoutOrder = 20
for i = 19, 1, -1 do -- ^same as above but for the decoy objects
local thisDecoy = crateInfo.DecoyObjects[i]
local foundItemData = framework.itemData.Halos[thisDecoy] or framework.itemData.Trails[thisDecoy] or framework.itemData['Particle Effects'][thisDecoy]
local itemLabel = createItemLabel(foundItemData)
itemLabel.LayoutOrder = i
itemLabel.Parent = clipBounds
end
newLabel.Parent = clipBounds
newCrate.Parent = framework.MainUI
local button = uiController:GetUIModule('ButtonGeneric').new(newCrate:WaitForChild('Spin')) -- create a button controller for the spin button
local colour = framework.shopInfo.RarityColours[crateType] -- get colours and whatnot for theming
newCrate:WaitForChild('Background').BackgroundColor3 = backgroundColour
newCrate:WaitForChild('Sides').BackgroundColor3 = backgroundColour
newCrate.BackgroundColor3 = backgroundColour
newCrate:WaitForChild('UIStroke').Color = colour
newCrate:WaitForChild('TitleContainer'):WaitForChild('TitleMain').Text = CRATE_TITLE:format(colour:ToHex(), crateType)
tweenService:Create(newCrate, TweenInfo.new(1, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out), {Position = UDim2.fromScale(.5, .5)}):Play() -- part where the frame should go on-screen
task.wait(0.5)
fadeIn(button) -- fade in the spin button
button.MouseButton1Click:Wait() -- in the button controller, a custom click event is created so I can control when the input should be created
fadeOut(button) -- fade out the fade in button
task.delay(0.5, button.Destroy, button)
tweenService:Create(clipBounds, TweenInfo.new(1), {AnchorPoint = Vector2.new(random:NextNumber(0.05, 0.95), 0.5)}):Play() -- to simulate a random offset
uiPageLayout:JumpToIndex(99) -- finally, spin
local titleContainer = newCrate:WaitForChild('TitleContainer')
local now = tick()
-- irrelevant part omitted
task.wait(10)
local youGotLabel = itemsContainer:WaitForChild('YouGot')
youGotLabel.Text = formatYouGot(realItemData, crateInfo.Dupe) -- set the text
tweenService:Create(youGotLabel, TweenInfo.new(0.5), {TextTransparency = 0}):Play()
local okayButton: types.ButtonGeneric, equipButton: types.ButtonGeneric =
uiController:GetUIModule('ButtonGeneric').new(newCrate:WaitForChild('Okay')),
uiController:GetUIModule('ButtonGeneric').new(newCrate:WaitForChild('EquipNow'))
if crateInfo.Dupe then
okayButton._frameRef.Position = UDim2.fromScale(0.5, 0.9)
equipButton._frameRef.Visible = false
end
fadeIn(okayButton)
fadeIn(equipButton)
local yieldSignal = framework.signal.new() -- wait until one of the buttons has been clicked
local okConnection = okayButton.MouseButton1Click:Connect(function()
yieldSignal:Fire()
end)
local equipConnection = equipButton.MouseButton1Click:Connect(function()
yieldSignal:Fire()
framework.net:Fire('EquipCosmetic', { ToEquip = true; Name = crateInfo.ActualObject})
end)
yieldSignal:Wait()
framework.net:Fire('CrateFireServer', { GUID = crateInfo.CrateGUID }) -- to stop waiting for the client to spin the crate
tweenService:Create(newCrate, TweenInfo.new(1, Enum.EasingStyle.Back), { Position = UDim2.fromScale(0.5, -0.5) }):Play() -- move crate off-screen and destroy crate frame
task.delay(1, newCrate.Destroy, newCrate)
end
Does anyone have any ideas?