Unity
Unity — один из самых популярных игровых движков в мире: от инди-пиксель-арта до AAA-проектов. Логика пишется на C# прямо в редакторе, а сборка выполняется для ПК, мобильных и консолей.
1. Что такое Unity
Unity — это движок с редактором сцен и системой компонентов. Ты создаёшь игровые объекты, «вешаешь» на них компоненты (графика, физика, звук) и управляешь поведением через скрипты C#.
| Понятие | Описание |
|---|---|
| Scene | уровень игры или отдельный экран |
| Prefab | переиспользуемый «шаблон» объекта |
| Asset | любой ресурс: модель, текстура, звук, скрипт |
| URP | современный конвейер рендеринга по умолчанию |
Лицензия Personal бесплатна до годового дохода в 200 тысяч долларов.
2. Установка и первый проект
Скачай Unity Hub — менеджер версий движка:
- Установи Unity Hub и зарегистрируй аккаунт Unity.
- Во вкладке Installs добавь Unity 6 (или LTS) с модулями для нужных платформ.
- Создай проект по шаблону 3D (URP).
3. Интерфейс редактора
Главные окна Unity:
- Scene — рабочая область: размещение и редактирование объектов.
- Game — картинка с камеры игрока во время Play.
- Hierarchy — список всех объектов текущей сцены.
- Inspector — компоненты и параметры выбранного объекта.
- Project — файлы проекта (Assets).
- Console — ошибки, предупреждения и логи.
W/E/R — переместить, повернуть, масштабировать; F — сфокусироваться на объекте.4. Объекты, компоненты и Transform
Любой объект в сцене — GameObject. Его свойства задают компоненты: Transform (позиция, поворот, масштаб), Mesh Filter + Mesh Renderer (графика), Collider (столкновения).
Добавь куб:
- Hierarchy → ПКМ → 3D Object → Cube.
- Выбери куб — в Inspector появится компонент Transform.
- Измени Position, Rotation, Scale — объект сдвинется в Scene.
GameObject.CreatePrimitive(PrimitiveType.Cube);
new GameObject("Имя");Векторы работают через Vector3: transform.position += Vector3.up * 2f;
5. Сцены и сохранение
Сцена объединяет объекты уровня. Сохраняемая единица — .unity файл в папке Assets.
// Создать новую сцену в коде
SceneManager.CreateScene("Level2");
SceneManager.LoadScene("Level1");Переключение сцен настраивается в Build Settings → Scenes in Build.
6. Скрипты на C#
Создай скрипт: Project → ПКМ → Create → C# Script. Двойной клик откроет редактор кода (по умолчанию Visual Studio/Rider).
Базовый шаблон движения:
using UnityEngine;
public class Mover : MonoBehaviour
{
public float speed = 5f;
void Update()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
transform.Translate(x * speed * Time.deltaTime, 0, z * speed * Time.deltaTime);
}
}MonoBehaviour— базовый класс для скриптов Unity.Start()— один раз при старте;Update()— каждый кадр.Time.deltaTime— время кадра; всегда умножай на него движение.- Поля
publicвидны в Inspector и настраиваются без правки кода.
Отладка через консоль:
Debug.Log("Привет из Unity");
Debug.LogWarning("Внимание!");
Debug.LogError("Ошибка");7. Физика: Rigidbody и Collider
Компонент Rigidbody подключает объект к физическому движку: гравитация, толчки, столкновения. Collider задаёт форму для коллизий.
using UnityEngine;
public class Ball : MonoBehaviour
{
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * 8f, ForceMode.Impulse);
}
}
void OnCollisionEnter(Collision col)
{
Debug.Log("Столкновение с " + col.gameObject.name);
}
}OnTriggerEnter срабатывает, когда у коллайдера включён Is Trigger (сигнал без твёрдой стенки) — удобно для зон и предметов.8. Камера и освещение
Камерой определяется то, что видит игрок. Основные типы освещения — Directional (солнце), Point, Spot.
Сделай камеру «следящей»:
using UnityEngine;
public class FollowCam : MonoBehaviour
{
public Transform target;
public Vector3 offset = new Vector3(0, 3, -6);
void LateUpdate()
{
if (target != null)
{
transform.position = target.position + offset;
transform.LookAt(target);
}
}
}С помощью Light.intensity и цвета настраивается атмосфера сцены.
9. Префабы
Префаб — «заводской шаблон» объекта: экземпляры можно плодить в любой сцене, а правки префаба применятся сразу ко всем.
- Создай объект, добавь скрипты и компоненты.
- Перетащи его из Hierarchy в Project → получится префаб (синий куб в Project).
Создание экземпляра в коде:
public GameObject enemyPrefab;
public Transform spawnPoint;
void Start()
{
Instantiate(enemyPrefab, spawnPoint.position, spawnPoint.rotation);
}10. UI: Canvas и кнопки
Интерфейс живёт внутри Canvas. Создай кнопку: Hierarchy → ПКМ → UI → Button (Unity сама создаст Canvas и EventSystem).
Подключи обработчик:
- Скрипт
public void RestartGame()в классе. - В Inspector кнопки: поле OnClick → знак «+» → перетащи объект со скриптом → выбери метод.
using UnityEngine;
using UnityEngine.UI;
public class HUD : MonoBehaviour
{
public Text scoreText;
public void RestartGame() { }Текст меняется через scoreText.text = value.ToString();
11. Анимация: Animator
Анимации управляются через Animator Controller — граф состояний и переходов.
- Импортируй модель с анимациями (FBX) или создай Animation Clip.
- Создай Animator Controller в Project, добавь состояния Idle и Run.
- Переходы управляются параметрами (bool, float, int).
public Animator anim;
void Update()
{
anim.SetFloat("Speed", 1f); // параметр float
anim.SetBool("IsJumping", true); // параметр bool
anim.Play("Run"); // прямое воспроизведение
}12. Материалы и сборка игры
Материал определяет, как выглядит поверхность. В URP используй шейдер Universal Render Pipeline/Lit: задаются Base Map, Normal Map, Smoothness, Metallic.
Смена материала в коде:
public Material redMat;
void Start()
{
GetComponent<Renderer>().material = redMat;
}Сборка игры:
- File → Build Settings — добавь сцены и выбери платформу.
- Player Settings — название, иконка, текстуры.
- Build — получишь папку с игрой и исполняемым файлом.
13. Звук: AudioSource и AudioListener
Звук добавляется двумя компонентами: AudioListener («уши», обычно на камере) и AudioSource («источник»). В ролике (Audio Clip) подкладывается сам файл.
using UnityEngine;
public class CoinSound : MonoBehaviour
{
public AudioClip clip;
void OnTriggerEnter(Collider other)
{
AudioSource.PlayClipAtPoint(clip, transform.position);
}
}- 2D — звук без позиции, одинаковый в любом углу сцены (музыка);
- 3D — звук затухает с расстоянием, панорамируется (шаги, выстрелы);
- Mixer — группы громкости: музыка, эффекты, голос (Settings → Audio Mixer).
| Производительность | Рекомендация |
|---|---|
| Формат файла | OGG для музыки, WAV для коротких эффектов |
| Фильтры | не вешайте Reverb на каждый источник |
| Количество | десять-двадцать одновременно — комфортный максимум |
Time.timeScale = 0 не останавливает AudioSource сам по себе.14. Сохранение и загрузка: база
Сохранить игровой прогресс можно двумя способами: PlayerPrefs для простых значений и файлы JSON для структур. Начнём с простого хранилища.
using System;
using UnityEngine;
[Serializable]
public class SaveData
{
public int score;
public string level = "Level1";
}
public static class SaveSystem
{
public static void Save(SaveData data)
{
string json = JsonUtility.ToJson(data);
PlayerPrefs.SetString("save", json);
PlayerPrefs.Save();
}
}PlayerPrefsхранит пары ключ-значение (строки, числа, float);JsonUtilityсериализует класс в JSON за пару строк;- поля, которые сохранять не нужно, помечайте
[NonSerialized].
JsonUtility не любит словари и сложные вложенности — для больших данных используйте Newtonsoft JSON или базу данных.15. Оптимизация проекта
Заторможенная игра разочаровывает сильнее любого бага. Настройка фокуса: сначала профилирование, потом правки.
// Простой счётчик кадров
float fps;
void Update()
{
fps = 1f / Time.unscaledDeltaTime;
Debug.Log($"FPS: {fps:0}");
}- Profiler (Window → Analysis → Profiler) покажет, что тормозит: CPU, GPU или память.
- Draw Calls: меньше уникальных материалов, используйте атласы и статичный батчинг.
- Свет: запекайте статичное освещение (Baked), движущиеся тени — точечно.
- Объекты: отключайте те, что за камерой — пул врагов вместо создания новых.
Для мобильных целей есть отдельный профиль: включите Development Build и подключите Device Profiler. На телефоне картина часто противоположна редактору, поэтому финальные правки делаются по устройству.
16. Ввод и управление: Input System
Современный «Input System» пришёл на смену старому Input.GetAxis: управление описывается декларативно и поддерживает клавиатуру, геймпад и тач из одного набора Actions.
using UnityEngine.InputSystem;
public class PlayerMove : MonoBehaviour
{
[SerializeField] private InputActionReference moveAction;
[SerializeField] private float speed = 5f;
void Update()
{
Vector2 input = moveAction.action.ReadValue<Vector2>();
transform.position += new Vector3(input.x, 0, input.y) * speed * Time.deltaTime;
}
}- создайте Input Actions Asset: карта «Геймплей» с действиями Move, Jump, Interact;
- включите новый Input System в Player Settings (Active Input Handling);
- одноразовые действия — через
action.performed, непрерывные — через чтение вектора каждый кадр.
17. Корутины, async и пул объектов
Игровой цикл диктует свои способы асинхронности: корутины простаивают между кадрами, async/await получает результат из внешнего мира, а пул объектов убирает дорогое создание игровых объектов.
IEnumerator SpawnWave()
{
for (int i = 0; i < 10; i++)
{
SpawnEnemyFromPool();
yield return new WaitForSeconds(0.5f);
}
}
void Start() { StartCoroutine(SpawnWave()); }- корутина приостанавливается
yield-ом и продолжается на следующем кадре; - для HTTP-запросов используйте async/await с кастомной Awaitable;
- пул врагов: заранее созданные объекты «раздаются» и возвращаются вместо Instantiate/Destroy каждый бой.
Instantiate/Destroy в цикле дёргает GC и физику — на тысяче объектов это заметный «фриз».18. Основы мультиплеера: Netcode для GameObjects
Сетевой код удваивает сложность: состояние объектов — на сервере, а клиенты лишь предсказывают и синхронизируют. Официальное решение для старта — Netcode for GameObjects.
using Unity.Netcode;
using UnityEngine;
public class PlayerState : NetworkBehaviour
{
public NetworkVariable<int> Score = new(0);
[Rpc(SendTo.Server)]
public void TryPickupRpc()
{
Score.Value += 10;
}
}- хост владеет авторитетом: изменение счёта он рассылает всем;
NetworkVariableавтоматически синхронизирует изменение;- RPC бывают server- (игрок просит действие) и client- (сервер сообщает всем).
19. Навигация и ИИ: NavMesh
Враги и NPC, которые «разумно» обходят препятствия, в Unity решаются навигационной сеткой: NavMesh генерируется из геометрии уровня, а агенты ходят по ней.
using UnityEngine.AI;
public class EnemyAI : MonoBehaviour
{
private NavMeshAgent agent;
[SerializeField] private Transform target;
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
void Update()
{
agent.destination = target.position;
}
}- запеките NavMesh (Window → AI → Navigation) после расстановки препятствий;
- агенты обходят стены и поднимаются по площадкам без ручных правок пути;
- для толпы используйте несколько агентов и NavMeshObstacle, а не сотни одновременно.
20. ScriptableObject: данные отдельно от кода
ScriptableObject — контейнер данных, который живёт в проекте как ассет. Этим он сильнее полей в MonoBehaviour: конфигурация редактируется в Inspector отдельно от сцены и переиспользуется без копий.
// WeaponData.cs
[CreateAssetMenu(fileName = "Weapon", menuName = "Data/Weapon")]
public class WeaponData : ScriptableObject {
public string displayName;
public float damage;
public float fireRate;
}- один ассет — множество объектов: правка данных меняет все сцены, где он используется;
- балансеры меняют баланс без переписывания скриптов;
- дизайн-данные (предметы, враги, диалоги) живут как «листы» в проекте.
Архитектурный нюанс: храните в ScriptableObject только данные и «фабрики» конфигов, а логику — в отдельных классах, получающих их в RuntimeInitializeOnLoadMethod или через инъекцию.
21. Unity Test Framework: EditMode и PlayMode
Игру тестировать сложно, но возможно: Unity Test Framework (UTF) запускает юнит-тесты в двух режимах — EditMode (быстрый, без симуляции времени) и PlayMode (полная сцена, как в редакторе).
// EditMode-тест: логика без сцены
using NUnit.Framework;
public class DamageTests {
[Test]
public void DamageReducesHealth() {
var hp = new Health(100);
hp.TakeDamage(30);
Assert.AreEqual(70, hp.Current);
}
}- EditMode: чистая логика (математика, модели, инвентарь) — быстрые запуски;
- PlayMode: интеграция со сценой, объектами и физикой;
- запуск через Test Runner и CLI (batch mode) позволяет назначить тесты в CI.
Ставка на «чистые» системы (без MonoBehaviour-зависимостей) окупается: их можно покрывать в EditMode без симуляции и получить мгновенные результаты.
22. Addressables: управление контентом
Большой проект содержит сотни сцен и ассетов; грузить всё сразу — перебор. Addressables — система ссылок на «адресуемые» ассеты, которые загружаются в момент нужды и выгружаются, когда больше не нужны.
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class Loader {
AsyncOperationHandle<GameObject> op =
Addressables.LoadAssetAsync<GameObject>("enemies/Ork");
op.Completed += h => {
Instantiate(h.Result);
Addressables.Release(h);
};
}- ассет получает address (например, "level_5_music"), а не путь;
- паттерн Load → Use → Release предотвращает утечки памяти;
- Addressables интегрируются с Asset Bundles для обновления «на лету».
Это инструмент масштабирования: для маленьких игр он — лишний слой, но для крупных — способ держать память и время загрузки в рамках.
23. Монетизация, реклама и аналитика
Игра — продукт: после релиза нужно платить за сервер, покупать ассеты и, в идеале, зарабатывать. Три столпа — монетизация (встроенные покупки), реклама и аналитика событий.
| Способ | Когда работает |
|---|---|
| Разовая покупка | классическая игра с фиксированной ценой |
| IAP (встроенные покупки) | валюты, предметы, подписки |
| Реклама (AdMob/Unity Ads) | бесплатные игры, «за вознаграждение» |
- аналитика: события (старт уровня, покупка, рестарт) — в Amplitude/Firebase;
- ретеншн: D1/D7/D30 — «сколько игроков вернулось после дня»;
- A/B тесты цен и экономики — через удалённую конфигурацию.
Правило порядка: сначала геймплей и ретеншн, потом монетизация. Реклама «в лицо» на старте убивает игру быстрее, чем её отсутствие.
Что дальше
С языком C# ты уже познакомился в Unity. Для глубокого синтаксиса пройди базу языка Python (логика схожа), а для ГГ моделей и ассетов — Blender и Substance 3D Painter.