Your First Script

Scripts are components written in C#. You create a script file, attach it to a GameObject, and Unity runs its code while the game plays.

Step 1: Create the script

  1. In the Project window, right-click inside the Assets folder.
  2. Choose Create > Scripting > MonoBehaviour Script (in Unity 2022 and older: Create > C# Script).
  3. Name it Spinner right away, before pressing Enter.
The file name must match the class nameIf the file is Spinner.cs, the class inside must be public class Spinner : MonoBehaviour. If they don't match, Unity can't attach the script and shows "The script class cannot be found". If you rename the file later, rename the class too.

Step 2: Write some code

Double-click the script to open it in your code editor, and replace its contents with:

using UnityEngine;

public class Spinner : MonoBehaviour
{
    // Shows up in the Inspector so you can tweak it without editing code.
    public float degreesPerSecond = 90f;

    // Unity calls Update once every frame.
    void Update()
    {
        // Rotate around the Y (up) axis.
        // Multiplying by Time.deltaTime makes the speed "per second" instead of "per frame".
        transform.Rotate(0f, degreesPerSecond * Time.deltaTime, 0f);
    }
}

Save the file. Unity recompiles automatically when you switch back to the Editor. Check the Console for red errors.

Step 3: Attach it

  1. Create a cube: GameObject > 3D Object > Cube.
  2. Drag Spinner from the Project window onto the cube in the Hierarchy, or select the cube and click Add Component in the Inspector and search for "Spinner".
  3. Press Play. The cube spins.

What happens at runtime

  1. When you press Play, Unity loads the scene and creates an instance of your Spinner class for the cube.
  2. It fills in degreesPerSecond with the value shown in the Inspector.
  3. Every frame (often 60 or more times per second), Unity calls Update() on every active script.
  4. Your code rotates the cube by a small amount. Because the amount is multiplied by Time.deltaTime (the seconds since the last frame), the cube turns 90 degrees per second whether the game runs at 30 or 144 FPS.

Showing variables in the Inspector

Unity shows a field in the Inspector (this is called serialization) when it is either:

using UnityEngine;

public class Health : MonoBehaviour
{
    [SerializeField] private int maxHealth = 100;   // shown in Inspector, private to code
    [SerializeField, Range(0f, 1f)] private float armor = 0.2f; // shown as a slider
    [Header("Effects")]
    [SerializeField] private GameObject deathEffect; // drag a prefab here in the Inspector

    private int currentHealth; // NOT shown: private without [SerializeField]

    void Start()
    {
        currentHealth = maxHealth;
    }
}
The Inspector value winsThe value in your code (= 100) is only the default used when the component is first added. After that, the value saved in the Inspector is used. If you change 100 to 200 in code and nothing changes, check the Inspector (or right-click the component > Reset).

Talking to other components

Use GetComponent<T>() to get another component on the same GameObject. Do it once in Awake or Start and keep the result in a variable, rather than calling it every frame.

using UnityEngine;

public class ColorOnStart : MonoBehaviour
{
    private Renderer rend;

    void Awake()
    {
        rend = GetComponent<Renderer>(); // the Mesh Renderer on this cube
    }

    void Start()
    {
        rend.material.color = Color.red;
    }
}

To reference a component on a different GameObject, the easiest way is a serialized field that you fill by dragging in the Inspector:

[SerializeField] private Transform target; // drag any GameObject here

Common Mistakes

See also