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 seanjust530 · Aug 04, 2017 at 03:45 AM · 2dcoroutinecoroutines

Trouble understanding coroutines

I'm trying to make a flappy bird clone and I want it so that the player can't jump repeatedly as much as he wants. So I researched coroutines and realized that they would work for preventing the player from spamming jump without a cooldown. I've watched videos and looked at the unity documentation but I still can't understand what I'm doing wrong. Here is what I have in my player controller script:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerController : MonoBehaviour
 {
     //Declaring Variables:
     public Rigidbody2D rb;
     public bool canJump;
     // Use this for initialization
     void Start()
     {
         canJump = true;
     }
 
     // Update is called once per frame
     void FixedUpdate()
     {
         //Creates the force that pushes our player forward on the x axis
         rb.AddForce(new Vector2(600, 0) * Time.fixedDeltaTime, ForceMode2D.Force);
 
         //Jump
         if (Input.GetKey(KeyCode.Space) && canJump)
         {
             rb.AddForce(new Vector2(0, 2000) * Time.fixedDeltaTime, ForceMode2D.Force);
             canJump = false;
             StartCoroutine("JumpBreak");
             canJump = true;
         }
     }
 
     //Coroutine for preventing our player from spamming Jump
     IEnumerator JumpBreak()
     {
         Debug.Log("Start of coR");
         yield return new WaitForSeconds(2f);
         Debug.Log("End of coR");
     }
 }
 

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
1
Best Answer

Answer by eskivor · Aug 04, 2017 at 04:42 AM

Warning : If you get your inputs in a FixedUpdate () method, some of your inputs can be missed. Use an Update () method instead (I already had a bug like this in one of my previous projects).


Pro-tip : when you call your coroutine, avoid string as much as possible, StartCoroutine ("JumpBreak"); and StartCoroutine (JumpBreak ()); does the same thing, but with the second one, you'll have auto-complete in your IDE (mono develop, visual studio, etc.) and with that auto-complete, you have no chance to make a misprint in the name of the coroutine you are calling.


When you call your coroutine, consider as starting a parallel process with its own timeline. So when you call yield return new WaitForSeconds(2f); then only thing that will wait 2 seconds, are the lines under the yield in your coroutine, (here's your Debug.Log("End of coR");), nothing else. All the lines that are called after the StartCoroutine ();, will be executed, as it does normally, just after the previous line, at the same frame. So, as it, your canJump will be false, then true (coroutine or not) at the same frame. So at the end of the frame, canJump will stay true;


To fix it : put the canJump = true; line inside of your coroutine, after the yield line

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
2

Answer by thepopil · Aug 04, 2017 at 04:22 AM

I think you're pretty close. When you start a coroutine and call WaitForSeconds, it will just pause the function that it's called in. So the rest of FixedUpdate() is still being called after we start the coroutine, which means we're setting canJump immediately back to true.

Try moving the canJump assignments into the coroutine like this

 IEnumerator JumpBreak()
 {
     Debug.Log("Start of coR");
 
     canJump = false;
 
     yield return new WaitForSeconds(2f);
 
     canJump = true;

     Debug.Log("End of coR");
 }

This way, we set canJump to false when we first call the coroutine. And it won't get set back to true until we finish waiting.

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
0

Answer by seanjust530 · Aug 04, 2017 at 05:29 AM

Thank you both @thepopil and @eskivor . I really appreciate the advice and I actually got it to work! The only issue is it only works if I take off Time.deltaTime from the parameters in AddForce. I wanted to keep deltaTime so that i could run independent of the frame rate. Even if I can't fix that I'm grateful for the help.

Here is what I changed my script to:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PlayerController : MonoBehaviour
 {
     //Declaring Variables:
     public Rigidbody2D rb;
     public bool canJump;
     // Use this for initialization
     void Start()
     {
         canJump = true;
     }
 
     // Update is called once per frame
     void Update()
     {
         //Creates the force that pushes our player forward on the x axis
         rb.AddForce(new Vector2(600, 0) * Time.fixedDeltaTime, ForceMode2D.Force);
 
         //Jump
         if (Input.GetKey(KeyCode.Space) && canJump)
         {
             Debug.Log("Jump");
             rb.AddForce(new Vector2(0, 200), ForceMode2D.Force);
             StartCoroutine(JumpBreak());
         }
     }
 
     //Coroutine for preventing our player from spamming Jump
     IEnumerator JumpBreak()
     {
         Debug.Log("Start of coR");
         canJump = false;
         yield return new WaitForSeconds(0.5f);
         canJump = true;
         Debug.Log("End of coR");
     }
 }
 
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

127 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

Related Questions

Multiple coroutine exicution order 1 Answer

Coroutine only fires once instead of looping until stopped. 2 Answers

Need opinions, or facts, about how to best go about programming this behavior. Basically Redstone. 0 Answers

How to disable game elements for a fixed duration then re-enable them automatically, even if game is reopened 1 Answer

Shooting bullets OnMouseDrag, time delay issues 3 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