Unity array

3- Using Arrays to Control Objects in Unity

In this post, my goal is to use the Array in a simple project so that its use be clear, but keep in mind that this post is a continuation of the previous three posts, so if you haven’t read them, what you read here may be confusing. So read this post first, then this post, and if you think you need to know more about the method, read this post. I have uploaded the project file to Github according to the process we have had so far, you can download it from this link or open it with Github desktop software, which is better because you can get the next updates easily. The name of the file is SpeedControlArray, which is located in the Scenes folder.

But what is the story? In this project, we are going to write codes that will allow us to connect as many objects as we need in the Unity UI, so that we can make changes in them, such as changing their color, and we can also determine the speed and direction of their rotation.

First, we start with a model and consider one of the fans in the scene, for example, fan number one. In the Assets tab, we create a new script and name it SpeedControl, and then open it in Visual Studio and add the following three variables.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class speedcntltest : MonoBehaviour
{
    public GameObject rotatingFans;
    public Color colorField;
    public float fanRotationSpeed;
    
    void Start()
    {
        
    }

    void Update()
    {
        
    }
}

We use the first variable to control the rotation of the fan model. This is because almost everything in the Unity scene is a GameObject, so to access the component that controls the rotation of the fan model, we put the name of the GameObject class and then the variable name. What I’m saying is that anything in the Unity scene is a GameObject, which you can consider similar to System.Object in the .NET Framework, where everything comes from System.Object. In the Unity scene, GameObject is a base class for all objects. In the diagram below, the names of some of the most important Unity objects obtained from the GameObject class are specified, of course there are more of them:

Game Objects diagram

Line number eight is going to add a color picker to the Unity UI, so that we can use it to choose the color that I explained in the previous post. The ninth line is also a float variable with which we are going to control the fan rotation speed. All three of these variables have a public access type so that we can access them in the Unity UI.

Save here and return to Unity. Create a GameObject in the Hierarchy tab and attach the script to it. The result should be similar to the image below:

variables

First, connect the fan model to the Rotating Fans part and then add the following three lines to the Update method:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class speedcntltest : MonoBehaviour
{
    public GameObject rotatingFans;
    public Color colorField;
    public float fanRotationSpeed;
    
    void Start()
    {
         
    }

    void Update()
    {
        var myFanRenderer = rotatingFans.GetComponent<Renderer>();
        myFanRenderer.material.SetColor("_Color", colorField);
        rotatingFans.transform.Rotate(0.0f, 0.0f, fanRotationSpeed);
    }
}

The reason why we added these three lines to Update and not to the Start method is that we can still control the color and rotation after pressing the Play button in Unity. In addition, the third line must be in the Update method in order for the rotation to continue, otherwise, if you put it in Start, the value you set for it, for example, 60 degrees, will rotate before the first frame of execution and then it will remain fixed.

I explained about the two lines 18 and 19 in the first and second posts that their work is color change. In the third line, we tell the rotation variable in the transform component of the model that we have connected to our script in Unity to use the value entered in the Fan Rotation Speed for z-axis rotation, that is, the same value that we can set in the Unity UI. Save the file and go back to Unity and press the Play button.

The only thing that is a bit strange is the rotation speed of our model, which may be very fast on your PC even if the number is set to one. The reason is that here the rotation speed is not based on real time, for example one degree per second, but based on the power of the graphics card. It means that it is frame rate dependent, the more frames your graphics card can display in one second after pressing the Play button, the fan rotation speed will increase accordingly. You can see this by activating the Stats option in the Game window.

stats in Game mode

To solve it, our rotation number must be multiplied by something called “Time.deltaTime”. What is this job now? Its job is to calculate how much time has passed from the previous frame to the current frame based on seconds. This number is usually less than zero and is not constant, and the more powerful the graphics card is, the smaller the number will be. If we multiply this number by the amount of rotation, for example, one degree, if our model rotates one degree in one second, the amount of rotation for each frame will be determined.

rotatingFans.transform.Rotate(0.0f, 0.0f, fanRotationSpeed * Time.deltaTime);

So far, we have done the necessary work for one model, but what about more than one model? One way is to add to the number of code lines, for example, now that we have five lines, add 15 lines for the remaining three models and change only the names. What if there are more models? Well, this method is obviously not correct. This is where Array comes in. Its use is that instead of one thing, a number of something (a collection of similar types of data) can be stored in it, for example, instead of a rotation speed, we can store a number of different rotation speeds in it, as simple as that. To change the variables that we have now to an array type, after determining the type of the variable, put two open and closed brackets, like the example below:

public GameObject[] rotatingFans;
public Color[] colorField;
public float[] fanRotationSpeed;

With this, instead of 12 lines, we only have three lines to define the variables of the four fan models, but now if you look carefully, you will see that the lines inside Update show errors. The reason is that their variable type is different from the above variables. I think you guessed right, we have to add two brackets to them, but after adding the brackets, a small error remains under them. If, for example, we put zero in the brackets of these three lines 18, 19, and 20, the problem will be solved, but why? The reason is that when we define an array variable, for example, of the GameObject type, our variable stores the name of each model in the order we attributed to it. For example, it places the name of the first model in position number zero (always the first position of the array starts with the number zero) and the name of the second model in position number one and the rest in the same way. Now, to refer to the model stored in the array, we write the position number inside the brackets. That’s why Visual Studio doesn’t give an error when you put zero in the brackets.

var myFanRenderer = rotatingFans[0].GetComponent<Renderer>();
myFanRenderer.material.SetColor("_Color", colorField[0]);
rotatingFans[0].transform.Rotate(0.0f, 0.0f, fanRotationSpeed[0]*Time.deltaTime);

Save and return to Unity. You can see that the variables change and there is a zero value in front of each one, which basically determines the number of positions. Because we have four models, four color pickers and four rotation speeds, give all three four.

new Variables

After changing the value from zero to four, it creates four positions for each variable

new Variables

In this step, connect the fan models to the Rotating Fans section and set a desired color and rotation speed for each one. Click the Play button. You can see that only one of the fans is working. One way is to copy the lines like the example below and only change the numbers of the positions.

void Update()
{
    var myFanRendererA = rotatingFans[0].GetComponent<Renderer>();
    myFanRendererA.material.SetColor("_Color", colorField[0]);
    rotatingFans[0].transform.Rotate(0.0f, 0.0f, fanRotationSpeed[0] * Time.deltaTime);

    var myFanRendererB = rotatingFans[1].GetComponent<Renderer>();
    myFanRendererB.material.SetColor("_Color", colorField[1]);
    rotatingFans[1].transform.Rotate(0.0f, 0.0f, fanRotationSpeed[1] * Time.deltaTime);

    var myFanRendererC = rotatingFans[2].GetComponent<Renderer>();
    myFanRendererC.material.SetColor("_Color", colorField[2]);
    rotatingFans[2].transform.Rotate(0.0f, 0.0f, fanRotationSpeed[2] * Time.deltaTime);

    var myFanRendererD = rotatingFans[3].GetComponent<Renderer>();
    myFanRendererD.material.SetColor("_Color", colorField[3]);
    rotatingFans[3].transform.Rotate(0.0f, 0.0f, fanRotationSpeed[3] * Time.deltaTime);
}

Although it is not a good method and our three lines of code increased to 12 lines, but you can see that it works. But what is the better way? A better way is to use a feature called a For Loop, which executes a certain number of lines of code inside itself continuously. Read the full explanation about loops here. Now change the codes like the example below:

void Update()
{
    for (int i = 0; i < rotatingFans.Length; i++)
    {
        var myFanRenderer = rotatingFans[i].GetComponent<Renderer>();
        myFanRenderer.material.SetColor("_Color", colorField[i]);
        rotatingFans[i].transform.Rotate(0.0f, 0.0f, fanRotationSpeed[i] * Time.deltaTime, Space.Self);
    }
}

I think you have read the explanation about the loops, so now I will just say one thing about the above codes. In the three lines 20, 21, and 22, inside the brackets in front of the arrays, this time instead of the position number, we put the variable “i”, which we defined as a counter inside the loop brackets. With this, its value changes every time the loop is executed, and the codes inside the loop are applied to the next GameObject. For example, the first time the loop is executed, because the value of the counter is zero, then the color change and the determination of the rotation speed are applied to the number one fan model in the Unity UI. This is because the name of fan model number one is stored in position number zero. Then the counter updates itself and its value changes from zero to one. This time, it is the turn of the number two model in the number one position. This continues until the last model is connected to our script.

If you have any questions or comments, feel free to leave them in the comments section below.

Leave a Reply

Your email address will not be published. Required fields are marked *