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 /
  • Help Room /
avatar image
0
Question by soft_sound · Oct 01, 2015 at 04:55 PM · functionloopingtiming

Logic problem looping & timing

I'm having trouble calling a function at the correct time while looping. Either it calls it too fast or too slow. I thought I figured it out yesterday, but I didn't... Here is a diagram to show what I'm trying to do, I know I have some logic issue going on.

alt text

In Update() I call a function called blinkAtRandom(); This function has a timer that goes off X amount of time. When this timer goes off, it calls BlinkOnce();.

BlinkOnce() will change the texture for the eye animation, but only 1 texture per Y amount of time, so I want to loop through this eyelidTextures.Length amount of loops

The problem now, is looping ignores the timers so my results are either too "fast" (blink never can become false) or too "slow" (only changes 1 texture through an entire loop, and blink is always true).

Here is a sample of my code. I also want to point out if you stick BlinkOnce() by itself in update, it changes at the correct time and looks like Ideal Timing, so it works, it just can't be called from another function or I get the timing issues.

 int BlinkOnce(float resetTime)
     {
        
             if (blink)
             {
                 myTimer.x -= Time.deltaTime;
                 //timer finished
                 if (myTimer.x <= 0)
                 {
                     //StartCoroutine("OneBlink");
                     OneBlinkF();
                     myTimer.x = resetTime;
                     eyeFrame += 1;
                 }
 
                 //go through all of blink frames
                 if (eyeFrame > eyelidTextures.Length)
                 {
                     //stop blinking
                     blink = false;
                     eyeFrame = 0;
                 }
             }
         
             return 1;   
     }

Here is my other function

 void blinkAtRandom()
     {
         myTimer2 -= Time.deltaTime;
 
         if (myTimer2 <= 0)
         {
 
             //blink = true;
             for (int i = 0; i < eyelidTextures.Length; i++)
             {
                 BlinkOnce(myTimer.y);
            
             }
 
             //reset timer
             myTimer2 = Random.Range(eyeBlinkRange.x, eyeBlinkRange.y);
         }
     }

Both samples of code have been altered a great deal so they only show 1 of many test cases I've tried. This really should be easy, so I don't know how I ended up making this so complicated!

generalidea.png (41.9 kB)
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
0
Best Answer

Answer by _Gkxd · Oct 01, 2015 at 07:54 PM

The piece of code below will print "A" once every half second. You might find it useful.

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

 private IEnumerator DoSomethingEveryHalfSecond() {
     while (true) {
         Debug.Log("A");
         yield return new WaitForSeconds(0.5f);
     }
 }
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 soft_sound · Oct 06, 2015 at 08:27 PM 0
Share

I figured out the problem was, I needed to have 1 coroutine with a bunch of yields in it as opposed to 3 with each their own yield for x seconds. That was what was giving me the ti$$anonymous$$g trouble. Anyway, got my code working, thanks!

  IEnumerator blinkAtRandomI()
     {
         while (true)
         {
 
             for (int i= 0; i < eyelidTextures.Length; i++)
             {
                 //StartCoroutine(OneBlinkI(myTimer.y));
                 StartCoroutine("OneBlink");
                 yield return new WaitForSeconds(timeBetweenFrames);
                 Debug.Log(i);
             }
 
             Debug.Log("Done, time to restart~");
             var t = Random.Range(timeUntilNextBlink.x, timeUntilNextBlink.y);
             Debug.Log(t);
             yield return new WaitForSeconds(t);
   
         }
         
     }
avatar image
0

Answer by rageingnonsense · Oct 01, 2015 at 08:26 PM

Are you sure this is not because you are doing this in Update()? Update is not guarenteed to be called at fixed intervals, and could be contributing to the problem.

Try moving the code to FixedUpdate(), and see if it improves.

Also, _Gkxd's method would work.

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 soft_sound · Oct 01, 2015 at 08:57 PM 0
Share

Well, I have made them all into Coroutines but I'm still having trouble. FixedUpdate and LateUpdate won't fix a logic issue... :/

It flashes like mad now, but it's starting to sorta work, kinda, it flashes at the right time for one of my coroutines so I think I'm getting close, now if only I could get them to match up correctly and slowdown a bit... (Okay, I realized the ti$$anonymous$$g was better because I used the function version not the coroutine version, so I think I'll have to revert back to functions...) Update vs LateUpdate vs FixedUpdate really no noticeable difference in my scene btw. (Also since I'm using time.deltaTime it should be comparable to FixedUpdate...)

Hmmm... After more testing ~ coroutines are super fast so if there were some way to slow them down by like 90% I would be maybe okay... $$anonymous$$y blinkrange is 5-7 seconds, my resetTime is set to 15 seconds, timer2 set to 30sec... it just seems to be flickering.... I don't know coroutines seem to be a lot harder to control then regular functions... :/

And yes, yes timescale is set to 1.

 void FixedUpdate () {
 
         //blinkAtRandom();
         //BlinkOnce(myTimer.y);
         StartCoroutine("blinkAtRandomI");
     }

  

...

   IEnumerator blinkAtRandomI()
     {
             //blink = true;
             for (int i = 0; i < eyelidTextures.Length; i++)
             {
                 //BlinkOnce(myTimer.y);
                 StartCoroutine(OneBlinkI(myTimer.y));
                
             }
             blink = true;
             yield return new WaitForSeconds(Random.Range(eyeBlinkRange.x, eyeBlinkRange.y));
             //myTimer2 = Random.Range(eyeBlinkRange.x, eyeBlinkRange.y);
     }

...

  IEnumerator OneBlinkI(float resetTime)
     {
         while (blink)
         {
             
              StartCoroutine("OneBlink");
              eyeFrame += 1;
 
             //go through all of blink frames
             if (eyeFrame > eyelidTextures.Length)
             {
                 //stop blinking
                 blink = false;
                 eyeFrame = 0;
             }
 
             yield return new WaitForSeconds(resetTime);
         }
     }

....

avatar image _Gkxd soft_sound · Oct 02, 2015 at 12:29 AM 0
Share

The problem with your code right now is that you are starting a coroutine every time FixedUpdate (or Update) is called.

This means you're starting a coroutine every frame (in the case of Update), or every physics time step (in the case of FixedUpdate), which defeats the purpose of waiting for a certain amount of time. (I.e. the first coroutine will wait for some time, but during that time, another coroutine will run and make your image flash.)

I have provided a solution that avoids this problem by starting the coroutine inside Start, so that only one coroutine is running.

avatar image soft_sound _Gkxd · Oct 03, 2015 at 03:16 AM 0
Share

Well, I've moved it to start, it will probably work after I fiddle with it so more. Coroutines keep repeating, until I tell them to stop correct? It should work at some point so I'll go with your answer and give you the credit.

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

30 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

Related Questions

Unity update does not be called when lock screen 0 Answers

How do I convert this into C# and where should this be added? 1 Answer

Boolean set to true, false in Update() function because of Start() 1 Answer

onEnable & onDisable & onCollision never get called i have no idea y ?! 1 Answer

How to rotate camera 90 degrees but still keep control orientation in 2.5d? 0 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