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
1
Question by Matthew012 · Oct 20, 2013 at 12:38 AM · javascriptyield

Yield WaitForSecond is skipping after the first time.

When it repeats the function, it doesn't do the Yield, but if I go out of the range and go back into the range (See code for what I mean) it will do the yield, but if I stay in the range it just keep going and going without a pause.

 function Update () {
     //Follow function
     var playerPos = player.transform.position;
     dist = Vector3.Distance(playerPos,transform.position);
     if (dist > 1.0 && attack == false) {
         transform.position = Vector3.MoveTowards(transform.position, player.transform.position, Time.deltaTime*speed);
     }
     else {
         attack = true;
         if (attack == true) {
             attackPlayer();
         }
     } 
 }
 
 
 function attackPlayer() {
     yield WaitForSeconds(1.2);
     if( dist < 1.0 ) {
         var    pStats = player.GetComponent(playerStats);
         pStats.pLife -= baseDamage;
         pLife = pStats.pLife;
     }
     attack = false;
 }
Comment
Add comment · Show 2
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 Bunny83 · Oct 20, 2013 at 02:23 AM 1
Share

Just to make sure you understand what you're doing here. You start a new coroutine every frame. Each coroutine will wait 1.2 seconds and then does the attacking. When you come close enough you starting coroutines every frame and after 1.2 seconds the first started coroutine will attack. Since you started a new coroutine every frame, from now on every frame another coroutine will finish it's waiting time and attack.

avatar image Matthew012 · Oct 20, 2013 at 03:07 AM 0
Share

Ah that one helped, thanks. I figured it was something like that, cause I tried to prevent that but I couldn't.

2 Replies

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

Answer by aldonaletto · Oct 20, 2013 at 02:10 AM

If you want to respect an interval of 1.2s between attacks, the logic is wrong. WaitForSeconds only stops coroutines, not Update - you should use the boolean attack in a different manner in order to inhibit attacks while the coroutine is running:

 function Update(){
     if (dist > 1.0) { // out of attack range: chase player
         transform.position = Vector3.MoveTowards(transform.position, player.transform.position, Time.deltaTime*speed);
     }
     else // inside range: attack! 
     if (attack == false){ // but only if interval ended
         attackPlayer();
     }
 }

 function attackPlayer() {
     attack = true; // attacking now - don't call attackPlayer!
     var pStats = player.GetComponent(playerStats);
     pStats.pLife -= baseDamage; // apply damage
     pLife = pStats.pLife;
     yield WaitForSeconds(1.2); // wait interval
     attack = false; // interval ended: can attack again
 }
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 Matthew012 · Oct 20, 2013 at 02:49 AM 0
Share

But I want it to wait x seconds see if the player is still in attack range, if so then they get hit. Not an instance attack.

avatar image aldonaletto · Oct 20, 2013 at 03:02 AM 1
Share

Just change a little the function attackPlayer :

 function attackPlayer() {
     attack = true; // attacking now - don't call attackPlayer!
     yield WaitForSeconds(1.2); // wait interval
     if (Vector3.Distance(transform.position, player.transform.position) < 1.0){
       var pStats = player.GetComponent(playerStats);
       pStats.pLife -= baseDamage; // apply damage
       pLife = pStats.pLife;
     }
     attack = false; // interval ended: can attack again
 }
avatar image Matthew012 · Oct 20, 2013 at 03:14 AM 0
Share

Yeah thanks, after I read the comment in my question I understand what I was doing wrong, and you corrected it.

avatar image
2

Answer by Bunny83 · Oct 20, 2013 at 02:35 AM

In such a case it's way easier to use just a coroutine without Update:

 function Start()
 {
     var pStats = player.GetComponent(playerStats);
     while(true)
     {
         var playerPos = player.transform.position;
         if (Vector3.Distance(playerPos,transform.position) < 1.0)
         {
             yield WaitForSeconds(1.2);
             while(Vector3.Distance(playerPos,transform.position) < 1.0)
             {
                 pStats.pLife -= baseDamage;
                 pLife = pStats.pLife;
                 yield WaitForSeconds(1.2);
             }
         ]
         else
         {
             transform.position = Vector3.MoveTowards(transform.position, player.transform.position, Time.deltaTime*speed);
             yield;
         }
     }
 }

Just make sure you always yield each iteration or it will crash your game ;)

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 aldonaletto · Oct 20, 2013 at 03:09 AM 0
Share

This is a better alternative: the while infinite loop works as an Update that can be delayed by WaitForSeconds (actually, a PosUpdate, since it's executed after Update and before LateUpdate).

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

17 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

Related Questions

Walking sound change 0 Answers

Problem with yield waitForSeconds in for loop 0 Answers

Confused about Coroutines 2 Answers

How can I make a variable false for a period of time? 3 Answers

yield works, but yield WaitForSeconds does not? 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