Search Unity

Question Cycle trough array

Discussion in 'Scripting' started by getmyisland_dev, Aug 13, 2021.

  1. getmyisland_dev

    getmyisland_dev

    Joined:
    Dec 22, 2020
    Posts:
    100
    I want to make some camera static for my game and for that I have an image array, with some static images.

    In the update function I want to change them so that only one image is enabled at a time and it cycles through the images.

    Yeah, but now I'm stuck, because I have no idea on how to go further than that and to actually code it.

    This is what I have so far(not much):
    Code (CSharp):
    1. public Image[] staticImages;
    2.    
    3.     //float or int
    4.     float FramesPerSecond = 10.0f;
    5.  
    6.     void Start()
    7.     {
    8.        
    9.     }
    10.  
    11.     void Update()
    12.     {
    13.         int index = Time.deltaTime * FramesPerSecond;
    14.     }
    The index should cycle through and FramesPerSecond should define the speed. That's at least what makes sense to me.
     
  2. diXime

    diXime

    Joined:
    Oct 2, 2018
    Posts:
    162
    Hello,
    I would have gone for something like this.
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class Cycle : MonoBehaviour
    5. {
    6.     // cycling
    7.     public int secondsBetweenImages;
    8.     float secondsCounter;
    9.     // images
    10.     int numberOfDifferentImages;
    11.     int imagesCounter;
    12.  
    13.     private void Update()
    14.     {
    15.         // NOT in Update() !
    16.     }
    17.  
    18.     private void FixedUpdate()
    19.     {
    20.         secondsCounter += Time.fixedDeltaTime; // The counter increases by the fixed value of time between frames, i.e. 0.2 seconds usually
    21.         if(secondsCounter >= secondsBetweenImages) // checking for equal between floats and int is risky because of float inaccuracy, comparaison is better
    22.         {
    23.             secondsCounter = 0; // reset timer
    24.             ShowImage(imagesCounter); // or whatever you whish to do, like imageList[imagesCounter] or similar
    25. imagesCounter++;
    26.  
    27.             if (imagesCounter >= numberOfDifferentImages)
    28.                 imagesCounter = 0;
    29.         }
    30.     }
    31. }
    32.  
    33.  
    34.  
    35.  
    36.  
    EDIT : The concept is the same for cycling through the images, except secondsBetweenImages is numberOfDifferentImages, incrementing index, resetting it afterwards. I've modified the code above.
     
    Last edited: Aug 13, 2021
    getmyisland_dev likes this.
  3. getmyisland_dev

    getmyisland_dev

    Joined:
    Dec 22, 2020
    Posts:
    100
    This is really good and I'm gonna use it, but how can I do the array stuff. Like cycling through the array with an int or something.

    But thanks I will use that.
     
  4. diXime

    diXime

    Joined:
    Oct 2, 2018
    Posts:
    162
    A few points then:
    • You can't change the length of a given array. You must create a new one of the length you want.
    • Array elements can be access with array[index], index being the int value of the position of element, starting at 0
    • Don't forget to create your array. It's a very common mistake : either put all your elements in the component, or load the resources inside the component before using it. You'll get a "Null Reference Exception".
    • Don't forget to check for array length/null. You'd get a "Array Index Out of Bounds". Very common, too

    I've made your component here. Use it at your will, it's commented to help you understand what is done.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. public class Cycle : MonoBehaviour
    5. {
    6.     // cycling
    7.     public float secondsBetweenImages;  // I changed it to a float so you can have partial seconds too.
    8.     float secondsCounter;
    9.     // images
    10.     public RawImage image;
    11.     public Texture[] textureArray; // You need to initiate this
    12.     // ^ meaning put it in the component by dragging the images or setting them up with a loop of Resources.Load<Texture>("path") in Start().
    13.     int imagesCounter;
    14.  
    15.     private void Start()
    16.     {
    17.         // the Image Component. I usually use "raw image", it tends to render better.
    18.         // I'm assuming it's on the component on which you add this monobehaviour.
    19.         image = GetComponent<RawImage>();
    20.     }
    21.  
    22.     private void Update()
    23.     {
    24.         // NOT in Update() !
    25.     }
    26.  
    27.     private void FixedUpdate()
    28.     {
    29.         secondsCounter += Time.fixedDeltaTime; // The counter increases by the fixed value of time between frames, i.e. 0.2 seconds usually
    30.         if(secondsCounter >= secondsBetweenImages) // checking for equal between floats is risky because of float inaccuracy, comparaison is better
    31.         {
    32.             secondsCounter = 0; // reset timer
    33.             if (textureArray != null && textureArray.Length != 0 && imagesCounter < textureArray.Length)
    34.                 // take the habit of checking for those errors. If you forgot to put the images, the code won't break, and will advise you.
    35.             {
    36.                 image.texture = textureArray[imagesCounter]; // changing the image of the texture with the array element
    37.                 imagesCounter++; // incrementing the counter
    38.             }
    39.             else Debug.Log("You forgot to put the images in the component !");
    40.  
    41.             if (imagesCounter >= textureArray.Length) // resets the counter for the images
    42.                 imagesCounter = 0;
    43.         }
    44.     }
    45. }
    46.  
    47.  
    48.  
     
    Last edited: Aug 14, 2021