Roblox 在触摸时重复播放我的声音,导致 Studio 崩溃

问题描述 投票:0回答:1

我正在努力寻找一种方法来使这段代码正常工作。基本上,它的作用是为

Sound
文件夹中的每个
Position
创建父级
Positions
的克隆并播放它们,然后在游戏屏幕上播放字幕序列。

这是脚本的完整代码,因为它非常小(添加了一些上下文注释):

local Players = game:GetService("Players");
local RunService = game:GetService("RunService");

local col = script.Parent:WaitForChild("Collision", 30);
local audioPositions = script.Parent:WaitForChild("Positions"):GetChildren();
local voiceline = script.Parent;
local subtitleSequence = script.Parent:WaitForChild("SubtitleSequence"):GetChildren();

--[[Contains a function that creates an audio clone by passing the audio to clone
and a target parent which is used on this script (and as far as I know, it works)]]
local audioFunc = require(game:GetService("ReplicatedStorage").__AUDIO);
--[[Used to return the GameGui Subtitles text used to play out the subtitle sequence
(again, as far as I know, it works)]]
local gameUIFunc = require(game:GetService("ReplicatedStorage").__GAME_UI);

local touched = false;

local function RunSubtitleSequence()
    for i, subtitle in pairs(subtitleSequence) do
        local duration = subtitle:WaitForChild("Duration");
        
        local subtitleText = gameUIFunc.returnSubtitlesTextObject(Players.LocalPlayer);
        if subtitleText == nil then return; end;
        subtitleText.Text = subtitle.Value;
        wait(duration.Value);
    end;
    gameUIFunc.returnSubtitlesTextObject(Players.LocalPlayer).Text = "";
end;

col.Touched:Connect(function()
    RunService.Heartbeat:Wait();
    if touched then
        return;
    end;
    touched = true;
    RunService.Heartbeat:Wait();
    for i, audioPosition in pairs(audioPositions) do
        audioFunc.createSound(voiceline, audioPosition);
    end;
    RunService.Heartbeat:Wait();
    task.spawn(function()
        RunSubtitleSequence();
    end);
end);

这是围绕脚本和所有所需对象的结构:

|----Sound [SOUND]
|----|----Positions [FOLDER]
|----|----|----Position [PART]
|----|----|----Position [PART]
|----|----|----Position [PART]
|----|----SubtitleSequence [FOLDER]
|----|----|----0 [STRINGVALUE]
|----|----|----|----Duration [INTVALUE]
|----|----|----1 [STRINGVALUE]
|----|----|----|----Duration [INTVALUE]
|----|----VoicelineTrigger [LOCALSCRIPT]
|----|----Collision [PART]

我默认对脚本进行了反跳,因为这不起作用,我尝试做一些我认为有帮助的事情: -我尝试添加

RunService.Heartbeat:Wait();
来等待下一帧,但没有成功。 -我尝试将字幕序列放入带有
task.spawn(func)
的协程中,但它也不起作用。

我真的不知道这里出了什么问题

编辑:这是启动游戏时的堆栈跟踪:

  19:52:46.208  Infinite yield possible on 'ReplicatedStorage.__SCRIPTS.__VOICE_LINES:WaitForChild("Positions")'  -  Studio
  19:52:46.208  Stack Begin  -  Studio
  19:52:46.209  Script 'ReplicatedStorage.__SCRIPTS.__VOICE_LINES.VoicelineTrigger', Line 5  -  Studio - VoicelineTrigger:5
  19:52:46.209  Stack End  -  Studio

编辑2:可能无关紧要,但堆栈跟踪充满了其他“无限产量可能”的通知,但这是由于性能不佳(它们只是核心 ROBLOX 模块) 有什么办法可以解决吗

lua roblox
1个回答
0
投票

我不确定你为什么使用

RunService.Heartbeat:Wait();

在第一行。 Roblox 事件几乎同时工作,这意味着一旦调用某个事件,就可以在您的脚本处理另一个事件的调用所需的时间内再次调用该事件。这意味着它将创建大量事件调用,运行脚本相同的次数,直到

touched = true;

已达到,尽管执行您的代码的所有其他已运行线程都已在运行。

更好的方法是只让它执行一次代码,例如:

local function onTouch()
    ...
end

col.Touched:Once(onTouch)

只有当您完全意识到代码已被执行并且确实希望它再次监听事件时,才挂钩事件监听器。

© www.soinside.com 2019 - 2024. All rights reserved.