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
2
Question by jpthek9 · Feb 23, 2015 at 11:36 PM · fixedupdateinvokerepeatingstartcoroutinecycle

Custom fixed update cycle?

I want to call an event every X seconds where X is variable. I've looked into InvokeRepeating but it seems like I can't modify the rate after calling the method. I think the best way would be to use a repeating coroutine. Does StartCoroutine_Auto do this? I'm a bit confused as to how it works. If anyone can show me an example, I'd really appreciate it. 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

6 Replies

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

Answer by gfoot · Feb 24, 2015 at 02:22 AM

You can make a coroutine that waits arbitrary lengths of time between processing:

 private IEnumerator Coro()
 {
     while (true)
     {
         DoStuff();
         yield return new WaitForSeconds(HowLongShouldIWait());
     }
 }

 public void Start()
 {
     StartCoroutine(Coro());
 }

Not sure if it helps. It is equivalent to, but somewhat tidier than, summing up a float in your Update method and using that to decide whether it's time to "do stuff" yet or not. I prefer it a lot, though, especially compared to InvokeRepeating.

If you want more accurate callbacks than once per Update then you need to start your own thread. There is still always a limit to the extent to which you can get called at specific times under a multitasking operating system, let alone within C# code hosted by Unity, but I believe using a separate thread is the best you can do. There are also ways to ask Unity to call your coroutine at different points in the frame, e.g. during the next FixedUpdate or just before presenting a frame to the viewport, but these won't really help you either.

Using a separate thread, then, you just loop forever as above but call "Thread.sleep(XXX)" instead of "yield return ..." to wait for a while before continuing processing. It is not entirely accurate, so you probably want to combine it with a Stopwatch so that although you can't choose exactly when your code runs, you do know exactly when it runs.

Also beware of caveats using threads with Unity. I don't know for sure the status now, but in the past it has caused instability, especially if you don't proactively kill the threads when leaving play mode.

Comment
Add comment · Show 9 · 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 Jessespike · Feb 24, 2015 at 02:25 AM 1
Share

Just to be clear, coroutines are not threads. Update and coroutine both run on the main thread. Should avoid threading if possible.

avatar image jpthek9 · Feb 24, 2015 at 02:27 AM 0
Share

The WaitForSeconds() allows me to very easily adjust the rate of the cycle too. Thanks!

@jessespike Does this mean the coroutine is dependent on the frame rate?

avatar image Jessespike · Feb 24, 2015 at 02:35 AM 0
Share

you can use WaitForEndOfFrame(); which will make it execute every frame. You just need to compensate the difference in time between frames. e.g., myPosition.x += speed * Time.deltaTime;

avatar image gfoot · Feb 24, 2015 at 02:41 AM 0
Share

Sure, coroutines are not threads, they just look a bit like them. I mentioned threads as a separate option that can provide more accurate scheduling, in case you need a higher frequency callback than once per frame.

avatar image Bonfire-Boy · Feb 24, 2015 at 09:19 AM 1
Share

@gfoot Nice to see threads mentioned :) I see a lot of people on here saying "don't use threads in Unity" which is utter rot. Sure, one's limited in what one can do in threads but they work fine and when they're the right thing to use then one should definitely use them. They're just not often the right thing to use.

Show more comments
avatar image
3

Answer by Jessespike · Feb 24, 2015 at 02:23 AM

Coroutine can easily do this.

http://docs.unity3d.com/ScriptReference/Coroutine.html

http://unity3d.com/learn/tutorials/modules/intermediate/scripting/coroutines

  //A coroutine that loops and yields for X amount of time

  public float secondsToWait = 2f;
  public bool  isRunningCoroutine = true;

  private float elapsedTime = 0f;     
 
  void Start()
  {
      StartCoroutine( MyLoop() );
  }
 
  IEnumerator MyLoop()
  {
      while (isRunningCoroutine)
      {
          yield return new WaitForSeconds(secondsToWait);
          Debug.Log("Ding, firing event");
      }
      yield return null;
  }

If you want to update something else every frame that is based on deltaTime, I would put that in the update loop or in a seperate coroutine.

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 maccabbe · Feb 24, 2015 at 12:37 AM

If you want an event to be called every x seconds then you can use Update like following

 using UnityEngine;
 using System.Collections;
 
 public class NewBehaviourScript : MonoBehaviour {
     float time=0;
     public float x;
 
     void Update() {
         time+=Time.deltaTime;
         while(time>x) {
             time-=x;
             Event();
         }
     }
     void Event() {
         Debug.Log(x+" seconds have passed");
     }
 }
 

Edit: I would really encourage you to use Update or FixedUpdate over InvokeRepeating. However I think the following should be what you wanted.

 using UnityEngine;
 using System.Collections;
 
 public class NewBehaviourScript : MonoBehaviour {
     private float _x;
     private float lastInvokeTime;
     public float x {
         get {
             return _x;
         }
         set {    
             _x=value;
 
             float time=Mathf.Max(value-(Time.realtimeSinceStartup-lastInvokeTime), 0);
 
             CancelInvoke();
             InvokeRepeating("Event", time, value);
 
             Debug.Log("set x to "+value+" and first wait time to "+time);
         }
     }
     
     void Event() {
         Debug.Log(x+" seconds have passed");
         lastInvokeTime=Time.realtimeSinceStartup;
     }
 
     public float newX=1;
     void Update() {
         if(newX!=x) {
             x=newX;
         }
     }
 }


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 jpthek9 · Feb 24, 2015 at 12:42 AM 0
Share

Ah, thanks, but I'm looking for a little more accuracy and my game runs independent of frame rate. If the FPS were to drop to 5, I'd be in big trouble.

avatar image jpthek9 · Feb 24, 2015 at 02:23 AM 0
Share

Thanks for the update but how do I change the rate of InvokeRepeating after I call it?

avatar image maccabbe · Feb 24, 2015 at 04:34 AM 0
Share

The rate of InvokeRepeating is changed when x is changed. This is done by canceling Invoke then starting it up again with x as the time between invokes and x-(Time.realtimeSinceStartup-lastInvokeTime) as the time until next invoke.

avatar image
0

Answer by ekeldevious · Feb 24, 2015 at 03:37 AM

 c#
 
 public void TimerFunction(int x){
   invoke("targetfunction",x);
   invoke("TimerFunction",x)
 }

this is what I would do.

Comment
Add comment · Show 2 · 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 jpthek9 · Feb 24, 2015 at 03:56 AM 0
Share

How does that work?

avatar image ekeldevious · Feb 24, 2015 at 04:41 PM 0
Share

just change x at any time to space the function as desired

avatar image
-1

Answer by EggQuiz857 · Feb 24, 2015 at 02:32 AM

I would do some sort of one script activates it self. do it like this

 function Start()
 {
 wait();
 }
 
 function wait()
 {
 yield WaitForSeconds(5);
 doSomthing()
 }
 
 function doSomthing()
 {
 //do what you want in here
 }
 


simple

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
  • 1
  • 2
  • ›

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

InvokeRepeating OR Update OR FIxedUpdate? 2 Answers

Shooting Projectiles With controlling attackSpeed 0 Answers

Invoke repeating and StartCoroutine 1 Answer

What is the best between StartCoroutine or InvokeRepeating. 5 Answers

Pause between user mouse clicks 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