Search Unity

Controlling sprites in specific sequence

Discussion in 'Scripting' started by Herant89, Nov 12, 2020.

  1. Herant89

    Herant89

    Joined:
    Nov 1, 2020
    Posts:
    2
    Hello,

    I'm trying to build a path from object A to object B to light up in sequence. uniy_1.png show that when i run my script all path circles will activate or deactivate depending on current state, if i call function one more time it will flip.
    What i want ot achieve is being able to select number of circles to light up n, then start sequence, n number of circles will light for some give time, then sequence move to next circles by n numbers. And do it over and over again until function is deactivated. Images unity_2.png -unity_4.png show what i'm trying to achive.
    I'm not sure if i'm doing this currently or not, but the way i trigger a circle is by activate/deactivate Sprite Renderer for sprite prefabs inside a parent object.

    Here is my script so far:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3.  
    4. public class SolarSequence : MonoBehaviour
    5. {
    6.     void Update()
    7.     {
    8.         if (Input.GetKeyDown(KeyCode.Alpha1))
    9.         {
    10.             ToggleSolarSequence(0.05f);
    11.         }
    12.     }
    13.  
    14.     void ToggleSolarSequence(float speed = 0.1f)
    15.     {
    16.         StartCoroutine(CounterCoroutine(speed));
    17.     }
    18.  
    19.     private IEnumerator CounterCoroutine(float timeDelay = .1f)
    20.     {
    21.         foreach (SpriteRenderer sprite in GetComponentsInChildren<SpriteRenderer>())
    22.         {
    23.             sprite.enabled = !sprite.enabled;
    24.             yield return new WaitForSeconds(timeDelay);
    25.         }
    26.     }
    27. }
    28.  
    After a lot og googling and thinking i just cant to wrap my head around this, so hopefully someone has done such thing before.
     

    Attached Files:

  2. Mashimaro7

    Mashimaro7

    Joined:
    Apr 10, 2020
    Posts:
    727
    Maybe make an array of sprite renderers? Then pass it in in the method call like
    Code (CSharp):
    1. private IEnumerator CounterCoroutine(float timeDelay = .1f, SpriteRenderer[] sprites)
    Then run through a for loop in the coroutine,

    Code (CSharp):
    1.  
    2. private IEnumerator CounterCoroutine(float timeDelay, SpriteRenderer[] sprites)
    3.    {
    4.        for (int i = 0;i < sprites.Length; i++)
    5.        {
    6.             sprites[i].sprite.enabled = !sprites[i].sprite.enabled;
    7.             yield return [URL='http://www.google.com/search?q=new+msdn.microsoft.com']new[/URL] WaitForSeconds(timeDelay);
    8.        }
    9.     }
    10.  
    So one quick question, you want it to keep on activating/deactivating until it's turned off, and then what happens? All deactivate? Or does it stop at whatever sprite it was at and then pick up again after? Cause I can finagle that.

    Also it's not super important, but it's strange that you're declaring the value of "timeDelay" in your method call. Normally it would be something like,
    Code (CSharp):
    1. (float timeDelay)
    2. and then when you call the coroutine,
    3. [code=CSharp]StartCoroutine(CounterCoroutine(yourValue));
    But I see you're declaring the variable three times which doesn't make too much sense, because when you call
    Code (CSharp):
    1. ToggleSolarSequence(0.05f);
    it should be 0.05? But then you're setting it to 0.1 directly after. Here's how it should look,

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. public class SolarSequence : MonoBehaviour
    4. {
    5. public float delay = 0.05; //this isn't necessary, but let's you decide the value in the inspector :)
    6.  
    7.     void Update()
    8.     {
    9.         if (Input.GetKeyDown(KeyCode.Alpha1))
    10.         {
    11.             ToggleSolarSequence(delay);
    12.         }
    13.     }
    14.     void ToggleSolarSequence(float speed)
    15.     {
    16.         StartCoroutine(CounterCoroutine(speed));
    17.     }
    18.     private IEnumerator CounterCoroutine(float timeDelay)
    19.     {
    20.         foreach (SpriteRenderer sprite in GetComponentsInChildren<SpriteRenderer>())
    21.         {
    22.             sprite.enabled = !sprite.enabled;
    23.             yield return new WaitForSeconds(timeDelay);
    24.         }
    25.     }
    26. }
    27.  
     
  3. Herant89

    Herant89

    Joined:
    Nov 1, 2020
    Posts:
    2
    Thanks for taking the time to help me here, i did solve this in a quite messy way but i got the result that i wanted. It was quite easy to turn on three first sprites, then turn them off, then turn the next ones, ... But it did looked so laggy and not smooth at all. So what i had to do is to make sure that when i deactivating ones sprite i had to activate the spritie simultaneously on positive offset direction. This way i managed to achieve this "rolling" effect, although indexing was a bit of a cluster to figure.

    Code (CSharp):
    1. private IEnumerator CounterCoroutine(float timeDelay)
    2.     {
    3.         SpriteRenderer[] sprite = GetComponentsInChildren<SpriteRenderer>();
    4.         int pathSize = GetComponentsInChildren<SpriteRenderer>().Length;
    5.         int index = 0;
    6.         for (int i = 0; i < pathSize / 3; i++)
    7.         {
    8.             if (index < 3)
    9.             {
    10.                 sprite[index].enabled = true;
    11.                 yield return new WaitForSeconds(timeDelay);
    12.                 sprite[index + 1].enabled = true;
    13.                 yield return new WaitForSeconds(timeDelay);
    14.                 sprite[index + 2].enabled = true;
    15.                 yield return new WaitForSeconds(timeDelay);
    16.             }
    17.             if (index < 27)
    18.             {
    19.                 sprite[index + 3].enabled = true;
    20.                 sprite[index].enabled = false;
    21.                 yield return new WaitForSeconds(timeDelay);
    22.                 sprite[index + 4].enabled = true;
    23.                 sprite[index + 1].enabled = false;
    24.                 yield return new WaitForSeconds(timeDelay);
    25.                 sprite[index + 5].enabled = true;
    26.                 sprite[index + 2].enabled = false;
    27.                 yield return new WaitForSeconds(timeDelay);
    28.             }
    29.  
    30.             if (index > 29)
    31.             {
    32.                 sprite[index-3].enabled = false;
    33.                 sprite[index].enabled = true;
    34.                 yield return new WaitForSeconds(timeDelay);
    35.                 sprite[index - 2].enabled = false;
    36.                 sprite[index + 1].enabled = true;
    37.                 yield return new WaitForSeconds(timeDelay);
    38.                 sprite[index - 1].enabled = false;
    39.                 sprite[index + 2].enabled = true;
    40.                 yield return new WaitForSeconds(timeDelay);
    41.                 sprite[index + 3].enabled = true;
    42.                 yield return new WaitForSeconds(timeDelay);
    43.  
    44.                 sprite[index].enabled = false;
    45.                 yield return new WaitForSeconds(timeDelay);
    46.                 sprite[index + 1].enabled = false;
    47.                 yield return new WaitForSeconds(timeDelay);
    48.                 sprite[index + 2].enabled = false;
    49.                 yield return new WaitForSeconds(timeDelay);
    50.                 sprite[index + 3].enabled = false;
    51.                 yield return new WaitForSeconds(timeDelay);
    52.             }
    53.             index += 3;
    54.         }
    55.     }
     
    Mashimaro7 likes this.