Совместная работа компонентов
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 4 из 50.
Небольшие компоненты тоже нуждаются друг в друге. 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 менять не придётся.
Задание
ЛегкоРывок фигуристки бесплатный: клавиша Space бросает её вперёд на 3 единицы (+z) при каждом нажатии. Сделайте рывок затратным по выносливости. Стрелки перемещают её на коньках (Mover.cs уже готов), а Stamina.cs уже восстанавливает current на regen в секунду, но не выше max (100).
- В Stamina добавьте открытый метод
bool TrySpend(float cost). Еслиcurrentне меньшеcost, он вычитаетcostизcurrentи возвращаетtrue; иначе оставляетcurrentбез изменений и возвращаетfalse. - Сделайте так, чтобы для Dash на объекте требовался компонент Stamina: Unity будет добавлять его каждый раз, когда добавляется Dash. Получите его один раз, в Awake, и сохраните в поле.
- Рывок стоит
cost(в Inspector задано значение 40). Space выполняет рывок, только если TrySpend разрешает это, а иначе выводит в журналToo tired.
Нажмите Play и выполняйте рывки, пока она не устанет, затем нажмите Check.
Попробуйте сами
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Сериализованные данные
Сериализуемые классыСписки в InspectorПеречисления в InspectorПовторение: таблица лута2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействия5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиВолны как данныеПовторение: база предметов