Динамически создаваемый GUI в Roblox - PullRequest
1 голос
/ 21 января 2020

Я пишу свою первую игру, используя lua и roblox studio. У меня есть пара вопросов относительно GUI. Я кодировал очень элементарный gui, который отображает код четырех команд, которые могут присоединиться к игре. Вот код для GUI. Он находится в локальном скрипте внутри Starter GUI:

local UpdateGUI = game.ReplicatedStorage:WaitForChild("UpdateGUI")
local StartGui = game.ReplicatedStorage:WaitForChild("StartGui")
local UpdateAllScoresLateArrival = game.ReplicatedStorage:WaitForChild("UpdateAllScoresLateArrival")

local function updateAllLabelsLateArrival(redPoints, bluePoints, yellowPoints, greenPoints)
    game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.Text = redPoints
    game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.Text = bluePoints
    game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.Text = yellowPoints
    game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.Text = greenPoints
end

local function UpdateLabel(plr, points)
    if plr.team.Name == "Really red Team" then
    game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.Text = points
    elseif plr.team.Name == "Really blue Team" then
    game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.Text = points
    elseif plr.team.Name == "New Yeller Team" then
    game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.Text = points
    elseif plr.team.Name == "Lime green Team" then
    game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.Text = points
    end
end

local localPlayer = game.Players.LocalPlayer


local function StartLabel(player)
    if player.Team.Name == "Really red Team" then

    game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.TextTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.TextTransparency = 0

    game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.TextStrokeTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.TextStrokeTransparency = 0

    game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.BackgroundTransparency = 0.5

    elseif player.Team.Name == "Really blue Team" then

    game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.TextTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.TextTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.TextStrokeTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.TextStrokeTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.BackgroundTransparency = 0.5

    elseif player.Team.Name == "New Yeller Team" then

    game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.TextTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.TextTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.TextStrokeTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.TextStrokeTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.BackgroundTransparency = 0.5

    elseif player.Team.Name == "Lime green Team" then

    game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.TextTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.TextTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.TextStrokeTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.TextStrokeTransparency = 0
    game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.BackgroundTransparency = 0.5
    end


end


UpdateGUI.OnClientEvent:Connect(UpdateLabel)

StartGui.OnClientEvent:Connect(StartLabel)

UpdateAllScoresLateArrival.OnClientEvent:Connect(updateAllLabelsLateArrival)

. Существует функция, которая запускает метку, которая запускается в скрипте на стороне сервера, когда игрок присоединяется к игре. Под «начать ярлык» я подразумеваю, что ярлыки там с прозрачностью 1, и функция делает их видимыми, когда игрок присоединяется. Существует функция, которая обновляет метку каждый раз, когда любой игрок забивает очки, и функция, которая также запускается, когда игрок поздно входит в игру, чтобы удостовериться, что у него есть очки игроков, уже находящихся в игре. Как я уже сказал, это моя первая игра, и я сосредоточился на том, чтобы все работало. Теперь я хотел бы правильно его кодировать. Моя цель - чтобы метки распределялись динамически. То есть, когда игрок присоединяется к игре, метка создается в коде. В частности, я бы хотел, чтобы расстояние между метками устанавливалось динамически, чтобы метки центрировались независимо от количества игроков. Я пытался сделать метки дочерними по отношению к «рамке», но метки поменялись местами и ими было сложно манипулировать. Поэтому я хотел бы получить несколько советов о том, как настроить это в коде.

1 Ответ

1 голос
/ 23 января 2020

Моя цель - чтобы метки выделялись динамически. То есть, когда игрок присоединяется к игре, метка создается в коде

Вы можете создавать элементы пользовательского интерфейса так же, как вы создаете экземпляры в рабочей области.

local lblTeam = Instance.new("TextLabel")
lblTeam.TextTransparency = 0
lblTeam.TextStrokeTransparency = 0
lblTeam.Name = teamName
lblTeam.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui

Я бы хотел, чтобы пространство между метками устанавливалось динамически, чтобы метки центрировались независимо от количества игроков.

Способ размещения элементов пользовательского интерфейса в Roblox со значениями UDim2 для размера и положения. Конструктор UDim2 выглядит так: UDim2.new(xScale, xOffset, yScale, yOffset). Масштаб относится к проценту от родительского контейнера, если этот размерный интервал, и Смещение - это количество пикселей, добавляемых дополнительно. Вот несколько примеров:

local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(0, 50, 0, 10) -- 50 pixel wide and 10 pixel tall
lbl.Size = UDim2.new(1, 0, 1, 0) -- 100% wide by 100% tall
lbl.Size = UDim2.new(1, -10, 1, -10) -- 100% wide and tall, minus 10 pixels on both bottom and right

-- assuming no changes to AnchorPoint...
lbl.Position = UDim2.new(0, 0, 0, 0) -- upper left corner is upper left corner of parent
lbl.Position = UDim2.new(0.5, 0, 0.5, 0) -- upper left corner is dead center
lbl.Position = UDim2.new(1, 0, 0, 0) -- upper left corner is offscreen on the right

Теперь, если вы хотите, чтобы ваши вещи были динамически размещены, вы могли бы вручную разместить эти объекты с помощью Positions, но я бы порекомендовал использовать UIListLayout объект и использование свойства LayoutIndex для автоматического размещения объектов для вас. Он автоматически обработает свойство Position для вас.

local function createTeamUI(name, parent, teamName, index)
    -- make a small frame to hold each team UI
    -- looks like : [[  Team Tag Label  ][ Team Points Label ]]
    local teamFrm = Instance.new("Frame")
    teamFrm.BackgroundTransparency = 1
    teamFrm.Size = UDim2.new(1, 0, 0, 30) -- relative to parent : 100% wide, 30px tall
    teamFrm.Name = name
    teamFrm.LayoutIndex = index

    local lblTeamTag = Instance.new("TextLabel", teamFrm)
    lblTeamTag.TextTransparency = 0
    lblTeamTag.TextStrokeTransparency = 0
    lblTeamTag.Name = "TeamTag"
    lblTeamTag.Text = teamName
    lblTeamTag.Size = UDim2.new(0.5, 0, 1, 0) -- relative to teamFrm : 50% wide, 100% tall
    lblTeam.Position = UDim2.new(0, 0, 0, 0)

    local lblPoints = Instance.new("TextLabel", teamFrm)
    lblPoints.TextStrokeTransparency = 0
    lblPoints.BackgroundTransparency = 0.5
    lblPoints.Name = "Points"
    lblPoints.Text = "0"
    lblPoints.Size = UDim2.new(0.5, 0, 1, 0) -- relative to teamFrm
    lblPoints.Position = UDim2.new(0.5, 0, 0, 0)

    -- optimization : set the parent last
    teamFrm.Parent = parent
    return teamFrm
end

local function createAllTeamLabels()
    -- creates a list of UI
    local frm = Instance.new("Frame")
    frm.Name = "Teams"
    frm.Size = UDim2.new(0.3, 0, 1, 0)
    frm.BackgroundTransparency = 1.0

    local layout = Instance.new("UIListLayout")
    layout.LayoutOrder = Enum.SortOrder.LayoutIndex
    layout.FillDirection = Enum.FillDirection.Vertical
    layout.Padding = UDim.new(0, 10) -- 10 pixels between each element in the list

    local frmTeamA = createTeamLabel("RedTeam", frm, "Really Red Team", 0)
    local frmTeamB = createTeamLabel("BlueTeam", frm, "Blue Team", 1)
    local frmTeamC = createTeamLabel("GreenTeam", frm, "Green Team", 2)

    frm.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui
end

local function updatePoints(teamName, points)
    game.Players.LocalPlayer.PlayerGui.ScreenGui.Teams[teamName].Points.Text = tostring(points)
end

Я заметил, что когда игрок умирает, GUI исчезает при возрождении

Существует свойство ScreenGuis называется ResetOnSpawn , которое можно изменить на false. Это сохранит пользовательский интерфейс даже после перезагрузки проигрывателя.

Поскольку вы динамически создаете свой пользовательский интерфейс в коде, вы должны быть осторожны, чтобы случайно не создать пользовательский интерфейс несколько раз. Вот где различия между StarterPlayer> StarterPlayerScripts и StarterPlayer> StarterCharacterScripts становятся важными. LocalScript внутри StarterPlayerScripts будет запускаться при первом подключении игрока, а LocalScript внутри StarterCharacterScripts будет запускаться каждый раз, когда персонаж игрока перезагружается. Поэтому будьте осторожны, когда запускаете код для создания пользовательского интерфейса.

Надеюсь, это поможет!

...