Урок 3 из 8 · 25 мин · обновлено
Первый скрипт на C#: Start, Update и переменные
Как создать скрипт и повесить его на объект, когда Unity вызывает Start и Update, какие бывают переменные в C# и как настраивать их в Inspector. Заставляем монету вращаться.
Скрипт — это компонент
Чтобы объект что-то делал сам, ему нужен скрипт на C#. Создадим первый:
- В окне Project: правая кнопка → Create → Scripting → MonoBehaviour Script, назовите
Hello. - Перетащите скрипт на любой объект в Hierarchy — он появится в Inspector как обычный компонент.
- Дважды щёлкните по скрипту, чтобы открыть его в редакторе кода.
Имя класса внутри файла должно совпадать с именем файла. Если переименовать одно без другого, Unity не сможет добавить скрипт на объект.
Start и Update
Напишем в скрипте:
using UnityEngine;
public class Hello : MonoBehaviour
{
void Start()
{
Debug.Log("Игра началась!");
}
void Update()
{
Debug.Log("Новый кадр");
}
}
Нажмите Play и откройте окно Console (Window → General → Console):
Игра началась!
Новый кадр
Новый кадр
Новый кадр
...
using UnityEngine;— подключаем всё, что даёт Unity;public class Hello : MonoBehaviour— наш класс является компонентом Unity;Start()Unity вызывает один раз, перед первым кадром. Здесь задают начальные значения;Update()вызывается каждый кадр — десятки раз в секунду. Здесь то, что меняется постоянно;Debug.Log()выводит сообщение в Console. Это главный способ посмотреть, что происходит в игре.
Каждая команда в C# заканчивается точкой с запятой, а блоки кода — в фигурных скобках.
Переменные в C#
C# — язык со строгими типами: при объявлении переменной пишут её тип.
int lives = 3; // целое число
float speed = 5.5f; // дробное число, в конце буква f
string playerName = "Шар"; // текст
bool isAlive = true; // да или нет
Буква f обязательна: без неё C# считает дробное число другим типом, double, и выдаст ошибку. Всё после // — комментарий.
Переменные, объявленные внутри класса, но вне методов, называют полями. Их видно во всех методах скрипта. А если перед полем написать [SerializeField], оно появится в Inspector:
[SerializeField] private float rotationSpeed = 90f;
private значит, что из других скриптов поле не видно, а [SerializeField] открывает его для редактора. Значение в коде — только начальное: в Inspector его можно поменять для каждого объекта отдельно, и Unity запомнит.
Time.deltaTime: скорость в секундах
Update вызывается каждый кадр, но кадров в секунду на разных компьютерах разное число: где-то 30, где-то 144. Если двигать объект на 1 градус за кадр, на мощном компьютере он будет вращаться в пять раз быстрее.
Time.deltaTime — сколько секунд длился прошлый кадр. Умножая скорость на него, мы получаем скорость «в секунду», одинаковую везде:
transform.Rotate(0, rotationSpeed * Time.deltaTime, 0);
transform — компонент Transform этого же объекта. Метод Rotate поворачивает объект на заданные углы по осям X, Y и Z.
Попробуйте сами. Напишите скрипт CoinSpin, который вращает монету вокруг вертикальной оси со скоростью, настраиваемой в Inspector. Повесьте его на префаб монеты.
Решение
using UnityEngine;
public class CoinSpin : MonoBehaviour
{
[SerializeField] private float rotationSpeed = 90f;
void Update()
{
transform.Rotate(0, rotationSpeed * Time.deltaTime, 0, Space.World);
}
}
Монета повёрнута на 90° по оси X, чтобы стоять на ребре. Поэтому её собственная ось Y смотрит вбок. Space.World говорит: вращай вокруг вертикальной оси мира, а не своей.
Скрипт добавлен в префаб, поэтому все пять монет вращаются сразу. Попробуйте во время игры поменять Rotation Speed в Inspector — монеты ускорятся.
Мини-тест: проверьте себя
Закрепите урок: несколько вопросов, разбор ответов — в конце.
-
Сколько раз за игру выполнится метод Start у объекта, который есть в сцене с самого начала?
Start срабатывает один раз, когда объект начинает работать. Для того, что повторяется постоянно, есть Update.
-
Как правильно объявить дробную переменную скорости в C#?
Дробные числа без буквы f C# считает типом double. Чтобы получилось число float, которое использует Unity, в конце пишут f.
-
Зачем полю скрипта атрибут [SerializeField]?
Поле с [SerializeField] видно в Inspector. Геймдизайнер может подобрать скорость, не открывая код, а у разных объектов могут быть разные значения.
-
Монета вращается быстрее на мощном компьютере и медленнее на слабом. Что забыли?
Update вызывается каждый кадр, а кадров на разных компьютерах разное число. Time.deltaTime — время прошлого кадра: с ним скорость считается в секундах, а не в кадрах.