使用 rbx.lua,如何编辑 GUI 属性?

With rbx.lua, how do you edit GUI properties?

将 UI_ELEMENT.Visible 更改为 true,然后 false 显示并隐藏 UI 元素,但是当我再次将其切换为 true 时,它​​不会重新出现。我认为这可能是我如何做而不是我在做什么的问题。

你好, 我是 Roblox Lua 的新手(但我有 Javascript 和 C# 经验)。我正在制作 'Garage' 或 'Parts' GUI。我试图在文本对象上制作点击检测器,将 UI 元素的 UI_ELEMENT.Visible 设置为 true。一个文本按钮(前面提到的 UI 元素的一部分)将 UI_ELEMENT.Visible 设置回 false。

这个过程工作正常,直到我 运行 多次通过它(例如设置为 true,然后 false,然后再次为 true)。 UI_ELEMENT.Visible 是 'locked' 为真(因为将它设置为假只会导致它在下一帧被设置回真)但 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)。

有趣的是,我在 'another way that should work' 中提出的方法中的 none 实际上比循环的初始第一个循环更有效(例如设置为 true,然后为 false,然后为 true再次)。

同时记录测试以查看它们是否 运行 多次 运行 每次循环一次(就像它应该的那样)。但是,这意味着将其设置为可见的代码也是 运行ning,但不会记录错误或做它应该做的事情。

谢谢,丹尼尔·摩根

我认为问题出在您对服务器脚本和本地脚本的使用上。 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 事件已经 returns 了单击按钮的播放器对象。我使用 FindFirstChild 检查车库 GUI 是否存在。这可以防止潜在错误的发生,通常是一种很好的做法。

希望这对您有所帮助,如果您仍有问题,请跟进。