• 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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



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

Why Won't My Coroutine Yield? 2 Answers

What am I doing wrong with IEnumerator? 1 Answer

Waiting twice inside coroutine (C#) 2 Answers

Playing footsteps with interval 1 Answer

How does WaitForSeconds actually work behind the scenes? 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges