Hello! Are you tired of using SetPosition
everytime? Well fear not I have a script that reposition all of the touch buttons so you don’t have to call SetPosition
every single time.
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local TOUCH_BUTTON_POSITIONS: { UDim2 } = table.freeze({
UDim2.fromScale(0.2, -0.8),
UDim2.fromScale(-0.6, -0.6),
UDim2.fromScale(-0.8, 0.2),
UDim2.fromScale(0.4, -1.6),
UDim2.fromScale(-0.4, -1.4),
UDim2.fromScale(-1.2, -1.2),
UDim2.fromScale(-1.4, -0.4),
})
local TOUCH_BUTTON_SIZE = UDim2.fromScale(0.8, 0.8)
local JUMP_BUTTON_SIZE = NumberRange.new(70, 120)
local playerGui = Players.LocalPlayer.PlayerGui
local touchButtons: { ImageButton } = {}
local camera = workspace.CurrentCamera
local function createUICorner(parent: GuiObject)
local uiCorner = parent:FindFirstChildOfClass("UICorner") or Instance.new("UICorner")
uiCorner.CornerRadius = UDim.new(1)
uiCorner.Archivable = false
uiCorner.Parent = parent
end
local function handleTouchButtons(object: Object)
if not object:IsA("ImageButton") then
return
end
if object.Name == "ContextActionButton" then
local index = #touchButtons + 1
local position = TOUCH_BUTTON_POSITIONS[index]
if not position then
object:Destroy()
return
end
touchButtons[index] = object
object.Position = position
object.Size = TOUCH_BUTTON_SIZE
elseif object.Name ~= "ThumbstickFrame" and object.Name ~= "JumpButton" then
return
end
createUICorner(object)
end
local function isSmallScreen(): boolean
local viewportSize = camera.ViewportSize
local minAxis = math.min(viewportSize.X, viewportSize.Y)
return minAxis <= 500
end
local function getJumpButtonPosition(jumpButtonSize: number): UDim2
local xOffset = -(jumpButtonSize * 1.5 - 10)
local yOffset = -(if isSmallScreen() then jumpButtonSize + 20 else jumpButtonSize * 1.75)
return UDim2.new(1, xOffset, 1, yOffset)
end
local function handleContextButtonFrame(object: Object)
if not object:IsA("Frame") or object.Name ~= "ContextButtonFrame" then
return
end
local function onViewportSizeChanged()
local jumpButtonSize = if isSmallScreen()
then JUMP_BUTTON_SIZE.Min
else JUMP_BUTTON_SIZE.Max
object.Size = UDim2.fromOffset(jumpButtonSize, jumpButtonSize)
object.Position = getJumpButtonPosition(jumpButtonSize)
end
onViewportSizeChanged()
local viewportSizeChangedConnection =
camera:GetPropertyChangedSignal("ViewportSize"):Connect(onViewportSizeChanged)
object.Destroying:Once(function()
viewportSizeChangedConnection:Disconnect()
end)
end
local function handleContextActionGui(object: Object)
if not object:IsA("ScreenGui") or object.Name ~= "ContextActionGui" then
return
end
local function onPreferredInputChanged()
local preferredInput = UserInputService.PreferredInput
object.Enabled = preferredInput == Enum.PreferredInput.Touch
end
onPreferredInputChanged()
local preferredInputChangedConnection =
UserInputService:GetPropertyChangedSignal("PreferredInput"):Connect(onPreferredInputChanged)
object.Destroying:Once(function()
preferredInputChangedConnection:Disconnect()
end)
end
local function onDescendantAdded(descendant: Instance)
handleContextButtonFrame(descendant)
handleContextActionGui(descendant)
handleTouchButtons(descendant)
end
local function repositionTouchButtons()
for index, touchButton in touchButtons do
touchButton.Position = TOUCH_BUTTON_POSITIONS[index]
end
end
local function onDescendantRemoving(descendant: Instance)
local index = if descendant:IsA("ImageButton")
then table.find(touchButtons, descendant)
else nil
if not index then
return
end
if not table.remove(touchButtons, index) then
return
end
repositionTouchButtons()
end
for _, descendant in playerGui:GetDescendants() do
onDescendantAdded(descendant)
end
playerGui.DescendantAdded:Connect(onDescendantAdded)
playerGui.DescendantRemoving:Connect(onDescendantRemoving)
Preview: