Компоненты работают вместе
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 4 из 64.
Даже небольшие компоненты зависят друг от друга. Для Jetpack нужен Fuel на том же объекте, поэтому он находит Fuel один раз в Awake, сохраняет его в поле и обращается к нему через два небольших публичных метода:
public class Fuel : MonoBehaviour
{
public float amount = 10f;
public bool IsEmpty()
{
return amount <= 0f;
}
public void Burn(float units)
{
amount = Mathf.Max(amount - units, 0f);
}
}[RequireComponent(typeof(Fuel))]
public class Jetpack : MonoBehaviour
{
public float lift = 4f;
private Fuel fuel;
void Awake()
{
fuel = GetComponent<Fuel>();
}
void Update()
{
if (Keyboard.current.spaceKey.isPressed && !fuel.IsEmpty())
{
fuel.Burn(Time.deltaTime);
transform.position += Vector3.up * lift * Time.deltaTime;
}
}
}[RequireComponent(typeof(Fuel))] заставляет Unity добавлять Fuel при добавлении Jetpack — в редакторе или с помощью AddComponent — и не позволяет удалить Fuel, пока на объекте есть Jetpack. Unity проверяет это только в момент добавления Jetpack, поэтому Jetpack, который уже был на объекте до добавления атрибута, сохранит прежнюю конфигурацию. Awake — подходящее место, чтобы получить его: этот метод выполняется один раз, и к тому времени все компоненты самого объекта уже доступны.
Jetpack никогда не меняет amount самостоятельно. Fuel определяет, что значит сжигать топливо, например не позволять значению опускаться ниже 0, а Jetpack только отправляет запрос. Если позднее Fuel будет показывать шкалу или пополняться от подбираемых предметов, Jetpack не придётся менять.
Задание
ЛегкоСделай рывок фигуриста затратным по выносливости.
- В
Staminaдобавьpublic bool TrySpend(float cost): еслиcurrentне меньшеcost, вычти его и верниtrue, иначе —false. - Размести
[RequireComponent(typeof(Stamina))]надpublic class Dashи получи этот компонент в поле вAwake(). - При нажатии пробела выполняй рывок, только если
TrySpend(cost)возвращаетtrue; иначе выведи в журналToo tired.
Нажми «Играть»: после двух рывков в Console появится Too tired. Затем нажми «Проверить».
Попробуйте сами
using UnityEngine;
using UnityEngine.InputSystem;
public class Dash : MonoBehaviour
{
public float distance = 3f;
public float cost = 40f;
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
transform.position += Vector3.forward * distance;
}
}
}
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазинеПотренируйтесь самостоятельно: Песочница Unity