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



Changing UI_ELEMENT.可见为 true,然后 false 显示并隐藏 UI 元素,但是当我再次将其切换为 true 时,它不会再次出现。我相信这可能是我如何做的问题,而不是我正在做什么的问题。

你好 我是Roblox Lua的新手(但我有Javascript和C#经验(。我正在制作"车库"或"零件"GUI。我正在尝试在文本对象上设置UI_ELEMENT的点击检测器。UI 元素的可见值为 true。和一个文本按钮(前面提到的 UI 元素的一部分(设置了该UI_ELEMENT。可见回到假。

这个过程工作正常,直到我多次运行它(例如设置为 true,然后是 false,然后再次设置为 true(。UI_ELEMENT。可见被"锁定"在 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(。

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

谢谢,丹尼尔·摩根

我相信问题在于您使用服务器脚本和本地脚本。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()

这里有一个非常好的关于远程事件的指南: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

无需访问游戏。自 MouseClick 事件以来的玩家已返回单击按钮的播放器对象。我使用FindFirstChild来检查Garage GUI是否存在。这可以防止潜在错误的发生,并且通常是很好的做法。

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

最新更新