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 ForbiddenSoul · Nov 01, 2016 at 04:39 AM · coroutinecoroutinescoroutine errorsco-routine

Coroutine only fires once instead of looping until stopped.

Hi, and thanks for taking the time to help.

I'm trying to have all rigid bodies in my scene gravitate towards a(n) object(s) with a GravityWell C# script attached to them.

The idea of the following code is to run a new co-routine for each rigid body so that they handle applying force on their own.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class GravityWell : MonoBehaviour {
 
     // Use this for initialization
     void Start () {
         int i = 0;
         foreach (Rigidbody rigidbody in FindObjectsOfType<Rigidbody>())
         {
             i++;
             rigidbody.name = rigidbody.name + " " + i;
             StartCoroutine(Gravitate(rigidbody));
         }
     }
     
     // Update is called once per frame
     void Update () {
 
     }
 
     IEnumerator Gravitate(Rigidbody rigidbody)
     {
         rigidbody.AddForce(transform.position - rigidbody.position);
         Debug.Log("Gravitate() Coroutine is running with " + rigidbody.name);
         yield return new WaitForSeconds(.1f);
     }
 }
 

The Log output is shown for all rigid bodies in my scene, however it is only shown the first time instead of constantly filling up the log output as one would expect.

It's probably something simple I'm missing, but why are the co-routines not continuously running?

Thanks.

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

2 Replies

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

Answer by oStaiko · Nov 01, 2016 at 05:25 AM

Are you setting your object/script to unactive or destroying it? If the object/script starting the coroutine is no longer active, it'll cause the coroutine to hang and probably some other problems. Try making the Gravitate a public function, and see if that fixes it, and I'd highly recommend not touching the script that calls a coroutine.

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 pingFromHeaven · Nov 01, 2016 at 07:13 AM 0
Share

I had a very similar issue yesterday and this was the problem. Ended up using a static $$anonymous$$onoBehaviour for all coroutines.

 public static class CoroutineStarter
 {
     private static readonly $$anonymous$$onoBehaviour coroutineStarter;
     public static Coroutine StartCoroutine(IEnumerator function)
     {
         return coroutineStarter.StartCoroutine(function);
     }
 
     public static void StopCoroutine(IEnumerator function)
     {
         if (function != null)
         {
             coroutineStarter.StopCoroutine(function);
         }
     }
 
     static CoroutineStarter()
     {
         coroutineStarter = new GameObject("CoroutineStarter").AddComponent<$$anonymous$$onoBehaviour>();
         Object.DontDestroyOnLoad(coroutineStarter.gameObject);
     }
 }

Note that this won't work in 5.4, as adding pure $$anonymous$$onoBehaviours is forbidden. (I'm still using 5.3)

avatar image ForbiddenSoul · Nov 01, 2016 at 07:48 AM 0
Share

No I'm not setting the object/script to unactive or destroying it, yet. $$anonymous$$aking Gravitate() public yields the same result of only running once, rather than continuously. Possibly I have co-routines confused. I thought they were a function/method you could call that ran continuously like an update loop does until you stop them. Here this is not the case they fire once like a regular old function...

I realized that a script instance will actually fire up another co-existing update loop, so I simply attached a new script to all the objects with rigid bodies rather than having one script fire up the same amount of co-routines as I have now attached scripts.

In theory this way should cause more overhead, but it doesn't seem to, or is not noticeable.

Thanks for trying to help me out. If you know a better way let me know

What I use now:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class ForceGravitate : $$anonymous$$onoBehaviour {
     [SerializeField]
     Transform gravitateTowards;
 
     private float nextActionTime = 0.0f;
     private float tic = .1f;
 
     void Start () {
         //Find an object with an attached GravityWell script and use it's transform to gravitate towards
         gravitateTowards = FindObjectOfType<GravityWell>().transform;
     }
 
     void Update () {
         //If more time has passed than the value of a tic GravitateTowards
         if (Time.time > nextActionTime)
         {
             nextActionTime += tic;
             GravitateTowards(gravitateTowards);
         }
         
     }
 
     void GravitateTowards(Transform gravitateTowards)
     {
         // If we are farther than 4 units in magnitude away apply and keep aplying force, otherwise use default physics
         if (Vector3.$$anonymous$$agnitude(gravitateTowards.position - transform.position) > 4f)
         {
             GetComponent<Rigidbody>().AddForce(gravitateTowards.position - transform.position);
         }
     }
 }
 

avatar image ForbiddenSoul · Nov 01, 2016 at 09:03 AM 0
Share

Had another post refresh my memory you can call InvokeRepeating( ), which is probably what I really wanted, much simpler fix, and we can now just throw in gravity wells (still needs better application of forces) and anything with a rigid body get pulled towards them.

Thanks to you both for the help.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class GravityWell : $$anonymous$$onoBehaviour
 {
 
     // Use this for initialization
     void Start()
     {
         GravitateRepeating();
     }
 
     // Update is called once per frame
     void Update()
     {
 
     }
 
     void Gravitate()
     {
         foreach (Rigidbody rigidbody in FindObjectsOfType<Rigidbody>())
         {
             rigidbody.AddForce(transform.position - rigidbody.position);
         }
     }
 
     void GravitateRepeating()
     {
         InvokeRepeating("Gravitate", 0.1f, 0.1f);
     }
 }
avatar image
0

Answer by Zenix · Nov 01, 2016 at 09:46 AM

Coroutines don't automatically repeat, they work just like normal methods. If you want something to repeat, you'll have to add that functionality yourself.

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

63 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

Related Questions

Had difficulties implementing intro to Coroutines from unitypatterns.com. Help? 1 Answer

Does UnityEngine.CustomeYieldInstruction works in a seperate thread? 2 Answers

Coroutine not working - what I did wrong? 2 Answers

How to stop a coroutine started in Script A from within Script B 1 Answer

Coroutines not passing yield 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