So, I’ve been working on implementing a “Skip Cutscene” button for the game I’ve been working on. The script controlling the cutscene runs entirely in coroutines, as there needs to be multiple things happening at once, and at different intervals. Therefore, to implement a “Skip Cutscene” button, I should just have to implement coroutine.yield()
, right? Apparently not. Anyone know what to do about this? (The button works, but doesn’t get past any of the yields.)
--Skip Cutscene
skipGui.Button.Activated:Connect(function()
skipGui.Enabled = false
script.Parent.Parent.RemoteEvents.MainMenu.MenuEvent:Fire()
coroutine.yield(cutscene)
coroutine.yield(dialogue)
coroutine.yield(animations)
coroutine.yield(blackout)
end)
cutscene = coroutine.create(function()
--First half of cutscene script
--Calling the other coroutines
coroutine.resume(dialogue)
coroutine.resume(animations)
coroutine.resume(blackout)
--Second half of cutscene script
end)
Full script
local TweenService = game:GetService("TweenService")
local camera = game.Workspace.Camera
local cutsceneInfo
local tween
local moveTime
local delayTime
local cameraCounter = 1
local dialogueCounter = 0
local animationCounter = 0
local blackoutCounter = 0
local nextPosition
local nextDialogue
local nextAnimation
local nextBlackout
local dialogueGui = game.Players.LocalPlayer.PlayerGui:WaitForChild("CutsceneGui")
local dialogue
local animations
local blackout
local loadedAnim
local humanoid
local blackScreen = game.Players.LocalPlayer.PlayerGui:WaitForChild("BlackScreen")
local blackScreenTweenInfo = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0)
local chosenMap = game:GetService("ReplicatedStorage").Values.Chosen.ChosenMap
local debounce = false
local skipGui = game.Players.LocalPlayer.PlayerGui:WaitForChild("SkipCutscene")
local cutscene
--Cutscene Event
function startCutscene(deciderString)
cutscene = nil
dialogue = nil
animations = nil
blackout = nil
--Dialogue
dialogue = coroutine.create(function()
while true do
repeat
dialogueCounter += 1
nextDialogue = cutsceneInfo.Dialogue:FindFirstChild("Dialogue" .. dialogueCounter)
wait(tonumber(nextDialogue.DelayTime.Value))
dialogueGui.Enabled = true
dialogueGui.Speaker.Text = nextDialogue.Speaker.Value
dialogueGui.Speaker.TextColor3 = nextDialogue.SpeakerColor.Value
dialogueGui.Dialogue.TextColor3 = nextDialogue.SpeakerColor.Value
require(game:GetService("ReplicatedStorage").Functions.MiscFunctionStorage).Typewriter(nextDialogue.Value, dialogueGui.Dialogue)
wait(tonumber(nextDialogue.AfterDelayTime.Value))
dialogueGui.Enabled = false
until dialogueCounter == #cutsceneInfo.Dialogue:GetChildren()
dialogueCounter = 0
coroutine.yield(dialogue)
end
end)
--Animations
animations = coroutine.create(function()
while true do
repeat
if animationCounter ~= #cutsceneInfo.Animations:GetChildren() then
animationCounter += 1
nextAnimation = cutsceneInfo.Animations:FindFirstChild("Animation" .. animationCounter)
wait(nextAnimation.DelayTime.Value)
for _, id in pairs(cutsceneInfo.Parent:GetDescendants()) do
if id:IsA("IntValue") and id.Value == nextAnimation.HumanoidID.Value and id ~= nextAnimation.HumanoidID then
humanoid = id.Parent.Humanoid
break
end
end
humanoid:LoadAnimation(nextAnimation):Play()
end
until animationCounter == #cutsceneInfo.Animations:GetChildren()
animationCounter = 0
coroutine.yield(animations)
end
end)
--Blackout
blackout = coroutine.create(function()
while true do
repeat
if blackoutCounter ~= #cutsceneInfo.Blackout:GetChildren() then
blackoutCounter += 1
nextBlackout = cutsceneInfo.Blackout:FindFirstChild("Blackout" .. blackoutCounter)
wait(nextBlackout.Delay.Value)
blackScreen.Enabled = true
if nextBlackout.Value then
TweenService:Create(blackScreen.BlackScreen, blackScreenTweenInfo, {BackgroundTransparency = 0}):Play()
else
nextBlackout.BlackScreen.BackgroundTransparency = 0
end
if nextBlackout.Text.Value then
blackScreen.BlackScreen.TextLabel.Text = nextBlackout.Text.Text.Value
TweenService:Create(blackScreen.BlackScreen.TextLabel, blackScreenTweenInfo, {TextTransparency = 0}):Play()
end
wait(nextBlackout.AfterDelay.Value)
if nextBlackout.AfterFade.Value then
TweenService:Create(blackScreen.BlackScreen, blackScreenTweenInfo, {BackgroundTransparency = 1}):Play()
if nextBlackout.Text.Value then
TweenService:Create(blackScreen.BlackScreen.TextLabel, blackScreenTweenInfo, {TextTransparency = 1}):Play()
end
wait(1)
blackScreen.Enabled = false
else
blackScreen.Enabled = false
blackScreen.BlackScreen.BackgroundTransparency = 1
blackScreen.BlackScreen.TextLabel.TextTransparency = 1
end
end
until blackoutCounter == #cutsceneInfo.Blackout:GetChildren()
blackoutCounter = 0
coroutine.yield(blackout)
end
end)
cutscene = coroutine.create(function()
if not debounce then
debounce = true
game.SoundService.MainTheme:Stop()
blackScreen.Parent.Menu.PlayGui.Enabled = false
if deciderString == "End" then skipGui.Enabled = true end
blackScreen.Enabled = true
TweenService:Create(blackScreen.BlackScreen, blackScreenTweenInfo, {BackgroundTransparency = 0}):Play()
wait(1)
camera.CameraType = Enum.CameraType.Scriptable
cutsceneInfo = game.Workspace.LoadedMaps:FindFirstChild(chosenMap.Value).Cutscenes:FindFirstChild(deciderString).CutsceneInfo
camera.CFrame = cutsceneInfo.PartPositions.Part1.CFrame
wait(0.5)
blackScreen.Enabled = false
blackScreen.BlackScreen.BackgroundTransparency = 1
--Call other coroutines
coroutine.resume(dialogue)
coroutine.resume(animations)
coroutine.resume(blackout)
wait(tonumber(cutsceneInfo.PartPositions.Part1.DelayTime.Value))
--Camera Movement
repeat
if cameraCounter ~= #cutsceneInfo.PartPositions:GetChildren() then
cameraCounter += 1
nextPosition = cutsceneInfo.PartPositions:FindFirstChild("Part" .. tostring(cameraCounter))
moveTime = tonumber(nextPosition.MoveTime.Value)
delayTime = tonumber(nextPosition.DelayTime.Value)
tween = TweenService:Create(
camera,
TweenInfo.new(
moveTime,
Enum.EasingStyle.Sine,
Enum.EasingDirection.InOut,
0,
false,
0
),
{CFrame = nextPosition.CFrame}
)
tween:Play()
wait(tonumber(nextPosition.DelayTime.Value))
end
until cameraCounter == #cutsceneInfo.PartPositions:GetChildren()
--End cutscene
cameraCounter = 1
blackScreen.Enabled = true
TweenService:Create(blackScreen.BlackScreen, blackScreenTweenInfo, {BackgroundTransparency = 0}):Play()
wait(1)
game:GetService("ReplicatedStorage").Events.CutsceneTrigger:FireServer()
wait(0.5)
if deciderString == "Start" then
camera.CameraType = Enum.CameraType.Custom
camera.CameraSubject = game.Players.LocalPlayer.Character.Humanoid
else
script.Parent.Parent.RemoteEvents.MainMenu.MenuEvent:Fire()
end
blackScreen.Enabled = false
blackScreen.BlackScreen.BackgroundTransparency = 1
debounce = false
end
end)
coroutine.resume(cutscene)
--Skip Cutscene
skipGui.Button.Activated:Connect(function()
skipGui.Enabled = false
script.Parent.Parent.RemoteEvents.MainMenu.MenuEvent:Fire()
coroutine.yield(cutscene)
coroutine.yield(dialogue)
coroutine.yield(animations)
coroutine.yield(blackout)
end)
end
game:GetService("ReplicatedStorage").Events.CutsceneTrigger.OnClientEvent:Connect(startCutscene)