How to yield execution until a function is completed?

local TweenService = game:GetService("TweenService")
local SoundService = game:GetService("SoundService")
local ServerStorage = game:GetService("ServerStorage")

local Models = ServerStorage:WaitForChild("Models")
local Gaster_Blaster = Models:WaitForChild("Gaster Blaster")

local Gaster_Head = Gaster_Blaster:WaitForChild("Head")
local Charge_Up_Position = Gaster_Head:WaitForChild("Charge_Position")

local Charge_Up = Gaster_Blaster:WaitForChild("Charge_Up")
local Fire_Laser_Beam = Gaster_Blaster:WaitForChild("Fire_Laser_Beam")
local Awaken = Gaster_Blaster:WaitForChild("Awaken")

local Summon_Gaster_Blaster = script.Parent

local LocalPlayer = Summon_Gaster_Blaster.Parent.Parent.Parent.Parent
local character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = character:WaitForChild("Humanoid")
local HRP = character:WaitForChild("HumanoidRootPart")
local Head = character:WaitForChild("Head")

local Touch_Laser
local Fire_Beam
local MAX_RANGE = 500

local function Deactivate_Gaster(Cloned_Gaster_Head)
	for i, v in Cloned_Gaster_Head:GetDescendants() do
		if not v:IsA("MeshPart") then continue end
		TweenService:Create(v, TweenInfo.new(0.5, Enum.EasingStyle.Linear), {Color = Color3.fromRGB(255, 255, 255)}):Play()
	end
end

local function Prepare_Beam(Cloned_Gaster_Head)
	task.spawn(function()
		TweenService:Create(Cloned_Gaster_Head, TweenInfo.new(Charge_Up.TimeLength, Enum.EasingStyle.Bounce), {CFrame = Cloned_Gaster_Head.CFrame * CFrame.Angles(math.rad(25), 0, 0)}):Play()
	end)
	
	task.spawn(function()
		for i, Jaw in Cloned_Gaster_Head.Parent:WaitForChild("Jaws"):GetChildren() do
			TweenService:Create(Jaw, TweenInfo.new(Charge_Up.TimeLength, Enum.EasingStyle.Bounce), {CFrame = Jaw.CFrame * CFrame.Angles(math.rad(-5), 0, 0)}):Play()
		end
	end)
end

local Summon_Gaster = Summon_Gaster_Blaster.OnServerEvent:Connect(function(player)
	Fire_Beam = coroutine.create(function()
		local Gaster_Blaster_Clone = Gaster_Blaster:Clone()
		local Gaster_Blaster_Head_Clone = Gaster_Blaster_Clone:WaitForChild("Head")
		
		Gaster_Blaster_Clone.Parent = game.Workspace
		Gaster_Blaster_Clone:PivotTo(CFrame.new(Head.Position))
		
		Gaster_Blaster_Clone.Awaken:Play()
		
		for i, Eye in Gaster_Blaster_Head_Clone.Eyes:GetChildren() do
			TweenService:Create(Eye, TweenInfo.new(Awaken.TimeLength, Enum.EasingStyle.Linear), {Transparency = 0}):Play()
		end
		
		Prepare_Beam(Gaster_Blaster_Head_Clone)
		
		local Laser = Instance.new("Part")
		Laser.Color = Color3.fromRGB(255, 255, 255)
		Laser.Name = "Gaster_Laser"
		Laser.Size = Vector3.new(1, 1, 1)
		Laser.Material = Enum.Material.Neon
		Laser.Anchored = true
		Laser.CastShadow = false
		Laser.CanCollide = false
		Laser.Position = Charge_Up_Position.WorldCFrame.Position
		Laser.Parent = game.Workspace
		
		Touch_Laser = Laser.Touched:Connect(function(hit)
			if not hit.Parent:FindFirstChild("Humanoid") or hit.Parent.Name == player.Name then return end
			
			local Humanoid = hit.Parent:FindFirstChild("Humanoid")
			Humanoid:TakeDamage(Humanoid.Health * 0.25)
		end)
		
		Laser.Size = Vector3.new(4, 4, MAX_RANGE)
	end)
	
	coroutine.resume(Fire_Beam)
end)

I’m trying to yield the execution of the coroutine until the function Prepare_Beam is finished but I don’t know how to do that :thinking:

coroutine.yeild?

You could just run both the threads in Prepare_Beam in serial, because tweens play asynchronously anyway.

But, if you really want to keep them separate, just wait the tween length because they both use the same TweenInfo and therefore the same time length.

local function Prepare_Beam(Clone_Gaster_Head)
    --your code here
    --your code here

    task.wait(Charge_Up.TimeLength)
end

coroutine.yield is actually used for something completely different, I’m afraid. It’s basically used to return values from a coroutine whilst suspending its execution.

Thanks. I will try that! :thinking:

(yeeeeeet)

Wait, I want the tweens to run at the same time. I just want the coroutine to yield until the function is done.

Use a Boolean flag

local com

….


local function Prepare_Beam(Cloned_Gaster_Head)
	task.spawn(function()
		TweenService:Create(Cloned_Gaster_Head, TweenInfo.new(Charge_Up.TimeLength, Enum.EasingStyle.Bounce), {CFrame = Cloned_Gaster_Head.CFrame * CFrame.Angles(math.rad(25), 0, 0)}):Play()
	end)
	
	task.spawn(function()
		for i, Jaw in Cloned_Gaster_Head.Parent:WaitForChild("Jaws"):GetChildren() do
			TweenService:Create(Jaw, TweenInfo.new(Charge_Up.TimeLength, Enum.EasingStyle.Bounce), {CFrame = Jaw.CFrame * CFrame.Angles(math.rad(-5), 0, 0)}):Play()
		end
	end)
   com = true
end
for i, Eye in Gaster_Blaster_Head_Clone.Eyes:GetChildren() do
			TweenService:Create(Eye, TweenInfo.new(Awaken.TimeLength, Enum.EasingStyle.Linear), {Transparency = 0}):Play()
		end
		
		Prepare_Beam(Gaster_Blaster_Head_Clone)
   repeat task.wait() until com 

Just define com outside both functions

Okay, I will try that! :smiley:

(yeet)

It worked but I also want the entire model to look where my mouse is pointed at first and then keep looking at the nearest player but I’m not sure how to do that. I tried it but it kinda failed ;-;