Menu
CoddyTech

Совместная работа компонентов

Часть раздела Архитектура игр в 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 менять не придётся.

challenge icon

Задание

Легко

Рывок фигуристки бесплатный: клавиша 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;
        }
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Архитектура игр в Unity