Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 WesterlyCarrot9 · May 18, 2015 at 01:35 PM · c#animationcoroutineyieldienumerator

Yield Wait for Seconds (A little help here)

Alright so i have the code you can see below and what i want to happen is the enemy attacks the player once and the attack animation plays, then he waits for 10 seconds and then he attacks again and the animation plays again. However, with the below script he attacks all the time and the animation plays all the time too. Any suggestions? Notice that this is just a part of the code. That's why void Update(){ and other stuff is missing :P

 if (readyforattack) {
             if (!inRange ()) {
                 chase ();
             } else {
                 StartCoroutine(attacking());
             }
         }


 IEnumerator attacking(){
         GetComponent<Animation> ().Play (attack.name);
         yield return new WaitForSeconds (10);
         GetComponent<Animation> ().Play (attack.name);
     }



Comment
Add comment · Show 13
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 barbe63 · May 18, 2015 at 01:40 PM 0
Share

It can be in the other part of your code... If inRange is always true it will always attack for example.

It can also be the animation which is set to loop.

avatar image WesterlyCarrot9 · May 18, 2015 at 01:45 PM 0
Share

Well i just tried to set the animation to default and nothing. As for the inRange method it returns true only when the enemy is really close to the player for attacking.

avatar image karl_jones ♦♦ · May 18, 2015 at 01:48 PM 0
Share

How long does your attack animation take? Do you want a 10 sec delay after the attack animation, if so then add the animation time onto the 10.

avatar image karl_jones ♦♦ · May 18, 2015 at 02:02 PM 1
Share

Do this to add the delay onto the animation:

 yield return new WaitForSeconds (10 + GetComponent<Animation>()[attack.name].time );
avatar image barbe63 · May 18, 2015 at 03:22 PM 1
Share

Oh i think I found it ^^

Just prevent the coroutine from being called multiple times with a bool like this:

 if (readyforattack) {
              if (!inRange ()) {
                  chase ();
              } else if(!alreadyAttacking){
                  StartCoroutine(attacking());
              }
          }
  
  
  IEnumerator attacking(){
          alreadyAttacking = true;
          GetComponent<Animation> ().Play (attack.name);
          yield return new WaitForSeconds (10);
          GetComponent<Animation> ().Play (attack.name);
          alreadyAttacking = false;
      }

Edit: hmm just like karl jones suggested actually.

By the way why 2 attacks? Shouldn't it be just one per Coroutine?

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Tonks · May 18, 2015 at 05:11 PM

Just a tip, now that you have it working. Declare a WaitForSeconds in your private variables (private WaitForSeconds WFS;), then assign it as a new WaitForSeconds in your start function (WFS = new WaitForSeconds;), this way, you will save memory every time you call yield return new WaitForSeconds in your coroutine, as you can instead call the wait with yield return WFS (or whatever you called it) instead of instantiating a new WaitForSeconds each time.

A little memory optimisation tip for you :)

(Compare the two methods in the Unity Profiler if you want to know why this is a good idea)

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
avatar image
1

Answer by Paul-Sinnett · May 18, 2015 at 04:31 PM

You are starting multiple instances of the coroutine, one new one every frame, while readyforattack is true. You could try setting readyforattack to false before starting the coroutine and back to true when the coroutine is finished.

 if (readyforattack) {
     if (!inRange ()) {
         chase ();
         } else {
             readyforattack = false;
             StartCoroutine(attacking());
         }
     }
 }

 IEnumerator attacking(){
     GetComponent<Animation> ().Play (attack.name);
     yield return new WaitForSeconds (10);
     GetComponent<Animation> ().Play (attack.name);
     readyforattack = true;
 }
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

23 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

Related Questions

Waiting twice inside coroutine (C#) 2 Answers

Why Won't My Coroutine Yield? 2 Answers

What am I doing wrong with IEnumerator? 1 Answer

function behaves unexpectedly inside a coroutine. 2 Answers

IEnumerator's did not read "bool" after yield return new WaitForSeconds. 1 Answer


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