Урок 13 из 15

Интерфейс из кода: ScreenGui, кнопки и Scale

Создавать и оживлять интерфейс из LocalScript.

Теория

Интерфейс игрока — обычные объекты в дереве: ScreenGui, внутри Frame, внутри кнопки и надписи. Их можно расставить мышкой в StarterGui, а можно создать кодом — движок разницы не видит.

Управляет интерфейсом клиент: это LocalScript. Сервер к чужому экрану не лезет, он лишь присылает данные, а рисует их клиент.

Размеры задаются в UDim2 из двух частей: доля экрана и пиксели. Доля тянется вместе с экраном, пиксели остаются как есть. Отсюда правило: габариты — в долях, отступы — в пикселях.

  • UDim2.fromScale(0.4, 0.3) — сорок процентов ширины и тридцать высоты
  • AnchorPoint(0.5, 0.5) вместе с позицией 0.5, 0.5 ставит панель ровно по центру
  • Activated — правильное событие кнопки: работает и на тапе, и на геймпаде
  • TextScaled спасает от надписи, вылезающей за кнопку

Пример

Панель с кнопкой, которая считает нажатия.

StarterPlayerScripts/Counter.client.lua
  1. local Players = game:GetService("Players")
  2. local player = Players.LocalPlayer
  3.  
  4. local gui = Instance.new("ScreenGui")
  5. gui.Name = "Counter"
  6. gui.ResetOnSpawn = false
  7. gui.Parent = player:WaitForChild("PlayerGui")
  8.  
  9. local button = Instance.new("TextButton")
  10. button.Size = UDim2.fromScale(0.3, 0.1)
  11. button.Position = UDim2.fromScale(0.5, 0.85)
  12. button.AnchorPoint = Vector2.new(0.5, 0.5)
  13. button.TextScaled = true
  14. button.Text = "Нажми: 0"
  15. button.Parent = gui
  16.  
  17. local corner = Instance.new("UICorner")
  18. corner.CornerRadius = UDim.new(0, 12)
  19. corner.Parent = button
  20.  
  21. local clicks = 0
  22.  
  23. button.Activated:Connect(function()
  24. clicks += 1
  25. button.Text = "Нажми: " .. clicks
  26. end)

Задача

Добавь к панели вторую кнопку «Сброс», которая обнуляет счётчик. Расположи кнопки так, чтобы они не наезжали друг на друга на узком экране.

  • UIListLayout внутри Frame расставит кнопки сам
  • Не задавай кнопкам ширину в пикселях
Показать решение
StarterPlayerScripts/Solution.client.lua
  1. local frame = Instance.new("Frame")
  2. frame.Size = UDim2.fromScale(0.34, 0.2)
  3. frame.Position = UDim2.fromScale(0.5, 0.82)
  4. frame.AnchorPoint = Vector2.new(0.5, 0.5)
  5. frame.BackgroundTransparency = 1
  6. frame.Parent = gui
  7.  
  8. local layout = Instance.new("UIListLayout")
  9. layout.Padding = UDim.new(0, 8)
  10. layout.HorizontalAlignment = Enum.HorizontalAlignment.Center
  11. layout.Parent = frame
  12.  
  13. button.Parent = frame
  14. button.Size = UDim2.fromScale(1, 0.45)
  15.  
  16. local reset = button:Clone()
  17. reset.Text = "Сброс"
  18. reset.Parent = frame
  19.  
  20. reset.Activated:Connect(function()
  21. clicks = 0
  22. button.Text = "Нажми: 0"
  23. end)

Проверь себя

Где должен лежать скрипт, управляющий интерфейсом?

Показать ответ

Интерфейс — дело клиента: сервер чужой экран не рисует.

Почему габариты задают в Scale, а не в Offset?

Показать ответ

Пиксельная панель на маленьком экране занимает его целиком, доля — нет.