我的代码就像在一个while循环中一样,即使它不是
Posted
技术标签:
【中文标题】我的代码就像在一个while循环中一样,即使它不是【英文标题】:My code acts like it is on a while loop, even though its not 【发布时间】:2021-08-29 22:27:30 【问题描述】:我想让它在每次结束后播放 15 次警报。 我希望它能够工作,然后打印它已经完成。但是,它会无限打印它并最终冻结 Roblox Studio。
我已经研究和研究,声音结束事件仅在声音结束时触发,所以它不是多次触发的事件。我没有在 *** 上看到答案(如预期的那样)。
这是我的本地脚本:
-- 15 times
local warheadalarmevent = game.ReplicatedStorage:WaitForChild("WarheadAlarm")
warheadalarmevent.OnClientEvent:Connect(function()
script.WarheadAlarm:Play() -- 1st time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 2nd time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 3rd time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 4th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 5th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 6th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 7th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 8th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 9th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 10th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 11th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 12th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 13th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 14th time
script.WarheadAlarm.Ended:Connect(function()
script.WarheadAlarm:Play() -- 15th time
script.WarheadAlarm.Ended:Connect(function()
print("15 times")
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
end)
这是我的脚本(触发远程事件):
local alreadydone = false
function myfunction()
if alreadydone == true then
return
end
alreadydone = true
script.Parent.Parent.Button.Transparency = 1
script.Parent.Parent.FakeButton.Transparency = 0
script.Parent.Parent.Button.ClickDetector.MaxActivationDistance = 0
wait(.2)
script.Parent.Parent.Button.Transparency = 0
script.Parent.Parent.FakeButton.Transparency = 1
game.ReplicatedStorage.WarheadAlarm:FireAllClients()
game.Workspace.MordernTV.TV.SCREEN.SurfaceGui.Status.Text = "PRIMING"
game.Workspace.MordernTV.TV.SCREEN.SurfaceGui.Status.TextColor3 = Color3.new(1, 1, 0)
wait(30)
game.Workspace.MordernTV.TV.SCREEN.SurfaceGui.Status.Text = "PRIMED, ENGAGING.."
game.Workspace.MordernTV.TV.SCREEN.SurfaceGui.Status.TextColor3 = Color3.new(0, 1, 0)
end
script.Parent.ClickDetector.MouseClick:connect(myfunction)
我没有多次点击它或什么,发生了什么?
【问题讨论】:
【参考方案1】:您的代码中发生的情况是,您将越来越多的侦听器连接到同一事件,而从未断开任何连接。每次闹钟播放时,您都会连接另一个侦听器,以及连接更多侦听器的另一个函数。 Studio 崩溃是因为您创建了一个无限循环的函数,这些函数连接了函数,最终有太多的函数需要处理并且 Studio 崩溃了。
除了连接到 Sound.Ended 信号,您还可以调用信号的 Wait() 函数,该函数将在事件发生之前产生线程。因此,您可以在循环中使用它来确保警报一个接一个地触发,并跟踪警报已播放了多少次。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local warheadAlarm = script.WarheadAlarm
local warheadAlarmEvent = ReplicatedStorage:WaitForChild("WarheadAlarm")
-- create a debounce flag
local isAlarmPlaying = false
warheadAlarmEvent.OnClientEvent:Connect(function()
-- if alarm is already playing, escape
if isAlarmPlaying then
return
end
-- flip the debounce flag
isAlarmPlaying = true
-- play the alarm, and wait for each sound to finish
local callCount
for callCount = 0, 15, 1 do
warheadAlarm:Play()
warheadAlarm.Ended:Wait()
end
-- do the thing
print("15 times")
-- reset the debounce flag
isAlarmPlaying = false
end)
【讨论】:
【参考方案2】:(免责声明我并不真正了解 Roblox,但我认为这是一个很好的猜测,我确实读过一些关于它的信息。)
当您将函数连接到结束事件时,每次声音结束时都会调用它,而不仅仅是下一次。在第一次之后,将有多个功能连接到结束的事件,您可能不想要这些功能。而且,即使在第 15 次之后,前 14 个连接仍然存在并试图重放声音(一次多次播放声音也可能不好,将越来越多的功能连接到事件可能很快就会引起大问题随着连接数呈指数增长)。
这可能可以通过在第一次触发时断开每个连接来解决。但是,将一个函数连接到事件并使用一个最多为 15 的变量来确定是否重新触发声音可能会更容易。然后,如果您想再次使用声音对象,我想您仍然应该断开连接。
未经测试:
warheadalarmevent.OnClientEvent:Connect(function()
script.WarheadAlarm:Play()
local n = 0
local connection
connection = script.WarheadAlarm.Ended:Connect(function()
n = n + 1
if n < 15 then
script.WarheadAlarm:Play()
else
connection:Disconnect()
end
end)
end)
(请注意,该连接可能仍适用于任何尝试播放 script.WarheadAlarm
的内容,因此如果多个事物同时尝试播放此声音,您可能需要进一步重新考虑您的方法。)
【讨论】:
以上是关于我的代码就像在一个while循环中一样,即使它不是的主要内容,如果未能解决你的问题,请参考以下文章
C : 使用 && 运算符时是不是存在“惰性求值”,就像在 C++ 中一样?
DatabaseReference setValue 像在循环中一样工作