User interface 在Roblox中动态创建GUI
我正在使用lua和roblox studio编写我的第一个游戏。我有几个关于GUI的问题。我已经编写了一个非常基本的gui,它显示了可以加入游戏的四个团队的代码。下面是GUI的代码。它存在于StarterGUI中的本地脚本中:User interface 在Roblox中动态创建GUI,user-interface,dynamic,lua,roblox,User Interface,Dynamic,Lua,Roblox,我正在使用lua和roblox studio编写我的第一个游戏。我有几个关于GUI的问题。我已经编写了一个非常基本的gui,它显示了可以加入游戏的四个团队的代码。下面是GUI的代码。它存在于StarterGUI中的本地脚本中: local UpdateGUI = game.ReplicatedStorage:WaitForChild("UpdateGUI") local StartGui = game.ReplicatedStorage:WaitForChild("StartGui") loca
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,当玩家加入时,该函数使其可见。有一个功能,每当任何玩家得分时都会更新标签,还有一个功能,当玩家延迟加入游戏时也会触发,以确保它拥有游戏中已有玩家的得分。就像我说的,这是我的第一场比赛,我专注于工作。现在我想正确地编写代码。我的目标是动态分配标签。也就是说,当玩家加入游戏时,标签是用代码创建的。特别是我希望标签之间的空间是动态设置的,这样无论有多少玩家,标签都会居中。我试着把标签做成“框架”的子标签,但标签改变了位置,很难操作。所以我想要一些关于如何在代码中设置的建议
我的目标是动态分配标签。也就是说,当玩家加入游戏时,标签是用代码创建的
可以使用与在工作区中创建实例相同的方法创建UI元素
local lblTeam = Instance.new("TextLabel")
lblTeam.TextTransparency = 0
lblTeam.TextStrokeTransparency = 0
lblTeam.Name = teamName
lblTeam.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui
我希望标签之间的空间可以动态设置,这样无论有多少玩家,标签都可以居中
在Roblox中,UI元素的布局方式是使用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手动放置这些对象,但我建议您使用一个对象并使用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会在重生时消失
ScreenGUI上有一个名为的属性,可以更改为false。这将保持用户界面,即使在球员重置
因为您是在代码中动态创建UI,所以应该注意不要意外地多次创建UI。这里是StarterPlayer>StarterPlayerScript和StarterPlayer>StarterCharacterScript之间的区别变得重要的地方。StarterPlayerScript中的LocalScript将在玩家首次加入时运行,StarterCharacterScript中的LocalScript将在玩家的角色每次重新加载时运行。因此,在创建UI时,请注意触发代码的位置
希望这有帮助 嗨,这很有用。非常感谢Kylaaa。唯一的问题是索引不是动态创建的?例如,一对玩家加入游戏,他们玩了一段时间,这时我们应该有两个标签。然后第三个玩家稍后加入。然后我们有三个标签。也许我可以通过远程事件在OnPlayerAdded函数中使用您编写的CreateTeamUI函数?因此,当一个玩家加入时,我可以通过计算数组来获得索引:#Players:GetPlayers()这有意义吗?是的,可以。另一个选项是保留一个局部变量“teamCount”,并在调用CreateTeamUI()时添加+1。然后使用它,而不是传入索引。