Небольшие компоненты
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 1 из 50.
GameObject — это список компонентов, и каждый написанный тобой скрипт — ещё один компонент. Игры на Unity создаются так: каждому скрипту поручают одну задачу и добавляют на объект несколько скриптов. Перемещение, стрельба и очки здоровья игрока могли бы находиться в одном PlayerController, но, если разделить их на три компонента — Mover, Shooter и Health, — каждый из них можно будет добавлять и на другие объекты:
public class Health : MonoBehaviour
{
public int hp = 3;
public void TakeDamage(int amount)
{
hp -= amount;
if (hp <= 0)
{
Destroy(gameObject);
}
}
}- Игрок: Mover, Shooter, Health
- Турель: Shooter, Health
- Ящик: Health
При использовании обычных классов C# можно было бы создать иерархию: Character, затем ShootingCharacter : Character, а потом Player : ShootingCharacter. Турель стреляет, но не ходит, а ящик только ломается, поэтому для каждого нового типа объекта пришлось бы перестраивать иерархию. При использовании компонентов новый тип объекта — это новая комбинация уже существующих скриптов, собранных в Inspector, и у каждого скрипта там могут быть собственные значения: медленный Mover на одном объекте, быстрый — на другом.
Компоненты на одном объекте используют общий Transform, поэтому каждый из них должен изменять только ту часть, за которую отвечает. Mover, который прибавляет значения к x и z с помощью transform.position +=, не меняет y, поэтому Jumper на том же объекте всё ещё может менять высоту. А Mover, который задаёт всю позицию как new Vector3(x, 0.5f, z), каждый кадр возвращал бы y к прежнему значению и отменял прыжок.
Задание
ЛегкоBoat.cs выполняет сразу три задачи: стрелки (действие Move) управляют лодкой, лодка покачивается на волнах, а её лампа мигает. Утёнку тоже нужно покачивание, а бую — покачивание и мигание, поэтому в сцене им уже назначены компоненты Bobber и Blinker, а у лодки есть все три. Раздели код Boat.cs между ними:
- Bobber: каждый объект покачивается вокруг высоты, на которой он находится в начале, на
heightединиц вверх и вниз со своей скоростьюspeed(оба значения задаются в Inspector). Bobber изменяет только y-координату позиции, поэтому лодка по-прежнему может управляться. - Blinker: он включает и выключает
lamp(Renderer) каждыеintervalсекунд. - Boat оставляет только управление: удали код покачивания и мигания вместе с их полями.
Нажми Play и покатай лодку, затем нажми Check.
Попробуйте сами
using UnityEngine;
using UnityEngine.InputSystem;
// Один скрипт, три задачи: управление, покачивание и мигание.
public class Boat : MonoBehaviour
{
public float speed = 3f;
public float bobHeight = 0.1f;
public float bobSpeed = 2f;
public Renderer lamp;
public float blinkInterval = 0.5f;
private InputAction moveAction;
private float startY;
private float blinkTimer;
void Start()
{
moveAction = InputSystem.actions.FindAction("Move");
startY = transform.position.y;
}
void Update()
{
// управление
Vector2 input = moveAction.ReadValue<Vector2>();
transform.position += new Vector3(input.x, 0f, input.y) * speed * Time.deltaTime;
// покачивание
Vector3 p = transform.position;
p.y = startY + Mathf.Sin(Time.time * bobSpeed) * bobHeight;
transform.position = p;
// мигание
blinkTimer += Time.deltaTime;
if (blinkTimer >= blinkInterval)
{
blinkTimer -= blinkInterval;
lamp.enabled = !lamp.enabled;
}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыСовместная работа компонентовПовторение: модульная турель4Сериализованные данные
Сериализуемые классыСписки в InspectorПеречисления в InspectorПовторение: таблица лута2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействия5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиВолны как данныеПовторение: база предметов