使用 rbx.lua,如何编辑 GUI 属性?
Posted
技术标签:
【中文标题】使用 rbx.lua,如何编辑 GUI 属性?【英文标题】:With rbx.lua, how do you edit GUI properties? 【发布时间】:2020-10-14 05:52:41 【问题描述】:将 UI_ELEMENT.Visible 更改为 true,然后 false 显示和隐藏 UI 元素,但是当我再次将其切换为 true 时,它不会重新出现。我相信这可能是我如何做而不是我在做什么的问题。
嗨, 我是 Roblox Lua 的新手(但我有 javascript 和 C# 经验)。我正在制作“车库”或“零件”GUI。我正在尝试在文本对象上制作点击检测器,将 UI 元素的 UI_ELEMENT.Visible 设置为 true。并且一个文本按钮(前面提到的 UI 元素的一部分)将 UI_ELEMENT.Visible 设置回 false。
这个过程运行良好,直到我多次运行它(例如设置为 true,然后设置为 false,然后再次设置为 true)。 UI_ELEMENT.Visible 被“锁定”为 true(因为将其设置为 false 只会导致下一帧将其设置回 true),但 UI 不显示。
代码:
click_detector1.MouseClick:connect(function(player) -- When clicked
_G.PlayerInfo[player.Name].status = "In Garage" -- set player status to in garage (works fine no issues)
_G.PlayerInfo[player.Name].topbar = "" -- reset topbar (works)
print("this is only supposed to happen once") -- a check to see if this is running more than once
game.Players[tostring(player.Name)].PlayerGui.Garage.menu.Visible = true -- one way that should work
--.Enabled = true -- another way that should work
--.menu.Position = UDim2.new(0.5, 0, 0,0) -- another way that should work (setting position to center of screen)
end)
上面是一个服务器脚本(我们称之为脚本#1)。
button = script.Parent
local function onButtonActivated()
local Players = game:GetService("Players")
local player = Players.LocalPlayer -- get the local player
print("I am only running once") -- test to see if this is running more than once
game.Players[tostring(player.Name)].PlayerGui.Garage.menu.Visible = false -- one way that should work
--.Enabled = false -- another way that should work
--.menu.Position = UDim2.new(10, 0, 0,0) -- another way that should work (change x scale to off screen)
end
button.Activated:Connect(onButtonActivated)
以上是在本地脚本中(我们称之为脚本#2)。
有趣的是,我在“另一种应该起作用的方式”中提出的方法实际上都没有比循环的初始第一个周期更有效(例如,设置为 true,然后设置为 false,然后再次设置为 true)。
还记录测试以查看它们是否运行多次,每次循环通过时只运行一次(应该如此)。但是,这意味着将其设置为可见的代码也在运行,但没有记录错误或做它应该做的事情。
谢谢,丹尼尔·摩根
【问题讨论】:
如果我正确理解您的问题,您是在问为什么此代码在打开/关闭几次后开始失败? @Kylaaa 是的,我不明白。 【参考方案1】:我认为问题在于您使用服务器脚本和本地脚本。 LocalScripts 仅更改播放器客户端上的内容。非本地脚本会更改服务器上的内容。换句话说,非本地脚本会影响所有人,而本地脚本只会影响个别玩家。
通过 LocalScript 将 GUI 的可见性设置为 false 只会更改玩家客户端上的 GUI。但是,服务器仍会将玩家的 GUI 可见性视为真实。这种差异可能会给您带来问题。
我建议使用 RemoteEvents 的替代方法。我不会像在脚本 #2 中那样在 LocalScript 中将 GUI 可见性更改为 false,而是使用 RemoteEvent 来代替。在您的情况下,它看起来类似于以下内容:
以下是非本地脚本中的内容:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = Instance.new("RemoteEvent",ReplicatedStorage)
remoteEvent.Name = "MyRemoteEventName"
-- player is the player object, visibility is a boolean (true or false)
local function ChangeGuiVisibility(player, visibility)
player.PlayerGui.Garage.menu.Visible = visibility
end
-- Call "onCreatePart()" when the client fires the remote event
remoteEvent.OnServerEvent:Connect(onCreatePart)
您可以像这样从本地脚本触发此远程事件:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local visiblity = false
local remoteEvent = ReplicatedStorage:WaitForChild("MyRemoteEventName")
-- Fire the remote event.
remoteEvent:FireServer(visibility)-- NOTE: the player object is automatically passed in as the first argument to FireServer()
这是一个非常好的 RemoteEvents 指南:https://developer.roblox.com/en-us/articles/Remote-Functions-and-Events
基本上,RemoteEvents 允许您在客户端和服务器之间架起桥梁。客户端可以触发服务器将响应的事件。不久前,Roblox 并非如此。来自客户端的更改对服务器是可见的,这使得利用游戏变得非常容易。
另外,我想建议对您的第一个脚本进行一些更改,这可能对您将来有所帮助。 而不是:
game.Players[tostring(player.Name)].PlayerGui.Garage.menu.Visible = true
试试
if player.PlayerGui:FindFirstChild("Garage") then
player.PlayerGui.Garage.menu.Visible = true
end
没有必要访问 game.Players,因为 MouseClick 事件已经返回了点击按钮的玩家对象。我使用 FindFirstChild 检查 Garage GUI 是否存在。这可以防止发生潜在错误,通常是一种很好的做法。
希望这会有所帮助,如果您仍有问题,请跟进。
【讨论】:
以上是关于使用 rbx.lua,如何编辑 GUI 属性?的主要内容,如果未能解决你的问题,请参考以下文章
Rbx.Lua - 为啥我不能将 .txt 文件存储为表格?
xCode 4.2 核心数据如何在数据模型编辑器中使用 GUI 创建获取的属性?