Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

What is a more efficient method of making numerous coroutines?

Asked by 6 years ago
Edited 6 years ago

For the purposes of what I'm working on, I need all the parts of the player's character (head, torso, upper arms, lower legs, etc...) to fade out simultaneously. As far as I know, using coroutines would be the best way to go about this.

The problem I'm having is that there are 16 parts to the character's body, and to create a coroutine for each part to fading it to transparent seems sinfully ineffective.

To demonstrate what I mean, if I were to just want to fade out the Head and the UpperTorso, I would do this:

local fadeHead = coroutine.wrap(function()
    for i = 1, 25 do
        wait(0.05)
        head.Transparency = head.Transparency + 0.04
    end
end)

local fadeTorso = coroutine.wrap(function()
    for i = 1, 25 do
        wait(0.05)
        upperTorso.Transparency = upperTorso.Transparency + 0.04
    end
end)

fadeHead()
fadeTorso()

... and I'd be happy.

However, I would really like to know if there's a more efficient way of going about doing that for more than two or three items, at which point the code just becomes pretty horrid to behold.

I've tried a couple things - none of which I expected to work nor did.

Any suggestions are appreciated.

Thanks!

1 answer

Log in to vote
1
Answered by 6 years ago

A good question, though you I suspect that the number of coroutines you propose would not be a problem.

First, you can merge your current code into a single for loop:

for i = 1, 25 do
    wait(0.05)
    head.Transparency = head.Transparency + 0.04
    upperTorso.Transparency = upperTorso.Transparency + 0.04
end

This won't work if you wanted to be able to delay when the effect starts for certain body parts, but perfect otherwise.

If this is on the client, you can use the RunService for even smoother animation:

local RunService = game:GetService("RunService")

--When you want your animation to start:
local con
local startTime = tick()
con = RunService.Heartbeat:Connect(function(step)
    local progress = (tick() - lastTime)/1.25 -- 1.25 is the desired effect duration. Progress is now between 0 and 1 (where 1 means "at the end of the effect/animation")
    if progress >= 1 then
        progress = 1
        con:Disconnect()
    end
    head.Transparency = progress
    upperTorso.Transparency = progress
    --etc
end)

Even if you're on the server, comparing the elapsed time instead of repeatedly adding 0.05 to the transparency should produce smoother results -- wait will wait in increments of approximately 0.03 seconds and will not compensate if it waits extra long during some frames (meaning that the total animation time will be longer than 1.25 seconds using the for loop).

However, all of the above is unnecessary when Roblox offers a TweenService which does just what you're looking for. If we combine it with a for loop that iterates over all the character's parts, you needn't even name every body part individually (which you shouldn't do if you can help it, since different character models have different body part names, unless you've restricted the model type for the game).

local TweenService = game:GetService("TweenService")

--When you want your animation to start:
local ch = character:GetDescendants()
local tweenInfo = TweenInfo.new(1.25, Enum.EasingStyle.Linear)
local propertyList = {Transparency=1}
for i = 1, #ch do
    if ch[i]:IsA("BasePart") then
        local tween = TweenService:Create(ch[i], tweenInfo, propertyList)
        tween:Play()
    end
end
--You can do other stuff at this point, wait for 1.25 seconds to pass, or whatever you want.

Even if you don't want to use the TweenSevice, I recommend using the GetDescendants function instead of specifying each body part manually.

0
Brilliant! Exactly what I needed, and more for learning's sake. Thank you for taking the time to write such a helpful and comprehensive answer. LukeSmasher 619 — 6y
Ad

Answer this question