如何使用rbx.lua更改GUI属性?

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

嗨, 我是Roblox Lua的新手(但我有JavaScript和C#经验)。我正在制作一个“车库”或“零件”GUI。我正在尝试让文本对象上的点击检测器将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) - 当单击时


_G.PlayerInfo [player.Name]。状态=“在车库中” - 将播放器状态设置为在车库中(没有问题)

_G.PlayerInfo [player.Name]。topbar =“” - 重置topbar(工作)


print(“这只应该发生一次”) - 检查是否运行多次


game.Players [ tostring(player.Name)]。PlayerGui.Garage.menu.Visible = true --一种应该有效的方法

 - .Enabled = true - 另一种应该有效的方法

- .menu.Position = UDim2.new(0.5,0,0,0)- 另一种应该有效的方法(将位置设置为屏幕中央)

end)

以上内容是服务器脚本中的内容(让我们称其为脚本#1)。

button = script.Parent

local function onButtonActivated()

    local Players = game:GetService(“Players”)

    local player = Players.LocalPlayer-获取本地玩家

    print(“我只运行一次”)-测试是否多次运行

    game.Players [tostring(player.Name)]。PlayerGui.Garage.menu.Visible = false - 一种应该有效的方法

 - .Enabled = false - 另一种应该有效的方法

- .menu.Position = UDim2.new(10,0,0,0)- 另一种应该有效的方法(将x比例更改为关闭屏幕)

end

button.Activated:Connect(onButtonActivated)

上面是本地脚本(让我们称这个脚本#2)。的内容

有趣的事情是,我提出的“另一种应该有效的方法”中的任何一种都不能在循环的初始第一个周期之外起作用(例如,将其设置为true,然后为false,然后再次为true)。)

还记录测试以查看它们是否多次运行,每次循环时仅运行一次(就像应该的那样)。但是,这意味着为可见性设置代码也在运行,但未记录错误或执行其应该执行的操作。

谢谢,Daniel Morgan

点赞
用户13788973
用户13788973

我认为问题在于您使用了服务器脚本和本地脚本。LocalScript只会影响到玩家客户端上的内容,而非本地的脚本则会改变服务器上的内容。换句话说,非本地脚本会影响每个人,而LocalScript只会影响个别玩家。

通过LocalScript将GUI的可见性设置为false只会改变玩家客户端上的GUI。但是,服务器仍将视玩家的GUI可见性为true。这种差异可能会导致问题。

我建议使用RemoteEvents的替代方法。与您在脚本#2中所做的一样,不要在LocalScript中将GUI可见性更改为false,而是使用RemoteEvent进行更改。在您的情况下,它应该类似下面的代码:

下面是非本地脚本中的代码:

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local remoteEvent = Instance.new("RemoteEvent",ReplicatedStorage)
remoteEvent.Name = "MyRemoteEventName"

-- player是玩家对象,visibility是一个布尔值(true或false)
local function ChangeGuiVisibility(player, visibility)
    player.PlayerGui.Garage.menu.Visible = visibility
end

-- 当客户端触发远程事件时,调用“onCreatePart()”
remoteEvent.OnServerEvent:Connect(onCreatePart)

您可以像这样从本地脚本中激发这个远程事件:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local visiblity = false
local remoteEvent = ReplicatedStorage:WaitForChild("MyRemoteEventName")

-- 点燃远程事件。
remoteEvent:FireServer(visibility)-- 注意:玩家对象会自动作为第一个参数传递给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是否存在。这可以防止潜在的错误发生,通常是很好的做法。

希望这可以帮助您解决问题,请跟进如果您仍然遇到问题。

2020-07-01 17:31:34