Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Sync threaded coroutine?

Discussion in 'Scripting' started by rakkarage, May 30, 2015.

  1. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
    i have a tilemap
    when i am done procedurally generating i scan for animated tiles and start a coroutine animation for each
    some animations (like water) require sync for all animations be on the same frame at the same time

    2.gif

    it worked fine until i added threading ("and now you have two problems") to allow my loading animation to continue to play while generating and setting up

    1.gif

    without threading i can start ~4000 animations like this with no problem and they all start in sync and stay in sync

    3.gif

    now if i start more then 100 they start getting out of sync? hrm

    i tried WaitForEndOfFrame & WaitForFixedUpdate before the animations start but did not seem to help
    i tried adding a coroutine inbetween as a buffer but did not work
    i got it working by passing in a startTime set to Time.time + 5 but that is too slow for small maps and will be too fast if i add another 3k

    any help/ideas would be appreciated

    thanks

    Code (CSharp):
    1.         public void SetAnimation(int index, Tile.Level[] frames, float fps, bool sync = true)
    2.         {
    3.             UnityTask.RunOnMain(() => StartCoroutine(Animation(index, new Tile.Level[][] { frames }, fps, sync)));
    4.         }
    5.         public void SetAnimation(int index, Tile.Level[][] frames, float fps, bool sync = true)
    6.         {
    7.             UnityTask.RunOnMain(() => StartCoroutine(Animation(index, frames, fps, sync)));
    8.         }
    9.         private IEnumerator Animation(int index, Tile.Level[][] frames, float fps, bool sync)
    10.         {
    11.             var time = 1f / fps;
    12.             var animationIndex = 0;
    13.             var frameIndex = sync ? 0 : Utility.Random.Next(frames[animationIndex].Length);
    14.             yield return new WaitForEndOfFrame();
    15.             while (true)
    16.             {
    17.                 if (animationIndex >= frames.Length) animationIndex = 0;
    18.                 if (frameIndex >= frames[animationIndex].Length)
    19.                 {
    20.                     if (frames.Length > 1)
    21.                     {
    22.                         animationIndex = Utility.Random.Next(frames.Length);
    23.                         frameIndex = sync ? 0 : Utility.Random.Next(frames[animationIndex].Length);
    24.                     }
    25.                     else
    26.                         frameIndex = 0;
    27.                 }
    28.                 SetTile(index, (int)frames[animationIndex][frameIndex]);
    29.                 frameIndex++;
    30.                 yield return new WaitForSeconds(time);
    31.             }
    32.         }
    33.