使用 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 文件存储为表格?

如何在 Lua 中将图像转换为 JSON?

xCode 4.2 核心数据如何在数据模型编辑器中使用 GUI 创建获取的属性?

如何使用 Lwiit 资源编辑器创建主题或 GUI?

使用 QtPropertyBrowser 作为高级配置编辑器

如何在 GUI 中使用按钮打开单独的、可编辑的窗口?