Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by no_mercy_percy · May 31, 2020 at 03:09 PM · coroutineienumeratorstartcoroutinestackstopcoroutine

Item duration doesn't stack

Hey so i have PowerUps in my Scene and my Problem is that if i collect a PowerUp and its duration is for example 8 seconds. At Second 7, I collect the same PowerUp again but now the duration is 1s (from the PowerUp before) instead of 9s (the remaining Time of the last PowerUp + the PowerUp again): My Code:

 if (other.CompareTag("Powerup"))
         {
             playerAudio.PlayOneShot(collectSound, sfxVolume);
             powerUpIndicator.SetActive(true);
             hasPowerup = true;
             Destroy(other.gameObject);
             StartCoroutine(PowerUpCountdownRoutine());
 
         }


 IEnumerator PowerUpCountdownRoutine()
     {
         yield return new WaitForSeconds(powerupDuration);
         powerUpIndicator.gameObject.SetActive(false); 
         hasPowerup = false;    
     }


Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by KoenigX3 · May 31, 2020 at 03:18 PM

Instead of using Coroutines, use a timer variable in Update.

 float powerupTimer = 0;
 bool hasPowerup = false;
 
 void Update()
 {
    if(hasPowerup)
    {
       powerupTimer -= Time.deltaTime;
       if(powerupTimer < 0)
       {
          powerupTimer = 0;
          hasPowerup = false;
       }
    }
 }
 
 // When you get a powerup
 hasPowerup = true;
 powerupTimer += powerupDuration;
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image no_mercy_percy · May 31, 2020 at 10:56 PM 0
Share

Is it not possible to solve it with Coroutines? I have about 20 Items so far (All made with Coroutines) xD

avatar image KoenigX3 no_mercy_percy · Jun 01, 2020 at 12:27 PM 0
Share

As far as i know, when you called yield return WaitForSeconds in a coroutine, there is no way to stop the command and add another WaitForSeconds to it. You can only do that after the previous one has finished.

I came up with this solution, because i thought it would be the best in a situation like this. But i don't know whether you have different powerups with different timers to implement, and other factors. If you could show me how much the powerups differ from each other, maybe we could find a universal solution.

avatar image no_mercy_percy KoenigX3 · Jun 04, 2020 at 06:51 PM 0
Share

yeah i think it's the easiest way with a timer in Update

avatar image
0

Answer by superjustin5000 · Jun 01, 2020 at 12:36 PM

What about stopping it first in case it's already running by calling stopcoroutine, then startcoroutine

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image KoenigX3 · Jun 01, 2020 at 12:41 PM 0
Share

You still need to get the remaining time, and the coroutine won't return it, so you'll have to measure it yourself, with using timers again.

avatar image
0

Answer by ADiSiN · Jun 01, 2020 at 01:03 PM

Hi!

With the code that you shared you will need to re-design the Coroutine itself if you want to use Coroutine for that case. It might look like this:

 float f_PowerUpDuration = 0;
 Coroutine PowerUpCoroutine;
 
     if (other.CompareTag("Powerup"))
     {
         playerAudio.PlayOneShot(collectSound, sfxVolume);
         powerUpIndicator.SetActive(true);
         hasPowerup = true;
         Destroy(other.gameObject);
 
         // Add to current total f_PowerUpDuration value when receive powerup
         f_PowerUpDuration += PowerUpStack;
 
         // If PowerUpCorotuine null what means there is no coroutine running already - we start to execute one
         if(PowerUpCoroutine == null)
             PowerUpCoroutine = StartCoroutine(PowerUpCountdownRoutine());
             
 
     }
 
 IEnumerator PowerUpCountdownRoutine()
 {
     // While total f_PowerUpDuration > 0 we simply decreasing it over time
     while (f_PowerUpDuration > 0)
     {
         f_PowerUpDuration = f_PowerUpDuration - 1 * Time.deltaTime;
         yield return null;
     }
 
     powerUpIndicator.gameObject.SetActive(false);
     hasPowerup = false;
 
     // Reset Corotuine variable as well and overall time as well
     PowerUpCoroutine = null;
     f_PowerUpDuration = 0;
 }

So, we have total power up duration that called f_PowerUpDuration as well as PowerUpCoroutine the Coroutine type of variable to check if our Coroutine is already executing and to not stack them.

When we hit "Powerup" then we add to the overall time f_PowerUpDuration additional time of power up - the PowerUpStack.

Then we check PowerUpCoroutine and only in case if it's null, what means that there is no Coroutine already in execution, then we call and assign new Coroutine.


The Coroutine itself will decrease f_PowerUpDuration variable while it's more than 0 and only after remove your indicator, boolean and stored Coroutine variable. In case where you take powerup and already has Coroutine in execution, by increasing f_PowerUpDuration the Coroutine execution will automatically prolong since it's checking the total f_PowerUpDuration that we increased by taking up new power up.


You can adjust decreasing as you want, for example other way of decreasing might be like this:

  while (f_PowerUpDuration > 0)
  {
      yield return new WaitForSeconds(1f);
      f_PowerUpDuration--;
  }

So it's up to you.


Hope it helps.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

141 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Coroutine won't stop running. Tried String. 1 Answer

Brain exploding ... Problem with an internal Coroutine manager 3 Answers

yield return M() vs yield return StartCoroutine 2 Answers

Is there any performance differences between Coroutine methods ? 3 Answers

Can I use StartCoroutine inside of the same coroutine with a new variable? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges