Битва с боссом
Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 64 из 64.
Каменный голем охраняет выход из арены. Он топает в вашу сторону, а когда вы подходите близко, на секунду поднимает кулаки и обрушивает их на землю, нанося вам урон, если вы всё ещё рядом. После удара он отдыхает, и только тогда ваш меч может причинить ему вред: его каменная кожа не чувствует ударов, пока он идёт или готовится к удару. По цвету видно, что он делает: серый, когда идёт, красный, когда готовится к удару, голубой, когда отдыхает. Снизьте его здоровье до 0, и ворота откроются. Полоска в верхней части экрана обновляется после каждого удара.
Напишите мозг голема в виде машины состояний, создав класс для каждого состояния: Boss, а также ChaseState, WindupState и RestState в BossStates.cs. Игрок, полоска здоровья, ворота, IState, StateMachine и IDamageable уже готовы, а Boss уже создаёт свои состояния и обновляет машину.
Задание
СложноНапиши состояния голема в BossStates.cs.
ChaseState:Tint(Color.gray); двигайся к игроку со скоростьюspeed; при приближении на расстояниеslamRangeначинай подготовку к удару.WindupState:Tint(Color.red); черезwindupTimeвыведи в журналSlam!, нанеси игроку в радиусе урон в размереslamDamage, затем переходи в состояние отдыха.RestState:Tint(Color.cyan); черезrestTimeпреследуй игрока.Boss.TakeDamageучитывает урон только в состоянииrest: вычти указанное количество, вызови событиеHealthChanged, при значении 0 вызовиFall().
Нажми «Играть» и атакуй, пока он отдыхает. Затем нажми «Проверить».
Попробуйте сами
using System;
using UnityEngine;
using UnityEngine.Events;
public class Boss : MonoBehaviour, IDamageable
{
public Transform player;
public float speed = 2f;
public float slamRange = 2.5f;
public float windupTime = 1f;
public float restTime = 2f;
public int slamDamage = 2;
public int maxHealth = 6;
public event Action<int, int> HealthChanged;
public UnityEvent onDefeated;
public StateMachine machine;
public IState chase;
public IState windup;
public IState rest;
private int health;
void Awake()
{
health = maxHealth;
machine = new StateMachine();
chase = new ChaseState(this);
windup = new WindupState(this);
rest = new RestState(this);
}
void Start()
{
HealthChanged?.Invoke(health, maxHealth);
machine.ChangeState(chase);
}
void Update()
{
machine.Tick();
}
public void TakeDamage(int amount)
{
// Удары засчитываются только во время отдыха: уменьшите здоровье на amount, вызовите HealthChanged и Fall() при 0
}
// Готово: голем падает, ворота открываются, и голем покидает арену.
void Fall()
{
Debug.Log("The golem falls");
onDefeated.Invoke();
gameObject.SetActive(false);
}
// Расстояние до игрока по поверхности земли.
public float PlayerDistance()
{
Vector3 d = player.position - transform.position;
d.y = 0f;
return d.magnitude;
}
// Серый, пока он идёт; красный, пока готовится к удару; голубой, пока отдыхает.
public void Tint(Color color)
{
GetComponent<Renderer>().material.color = color;
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Архитектура игр в Unity
1Компоненты, а не иерархии
Небольшие компонентыБазовый скрипт врагаАбстрактные компонентыКомпоненты работают вместеПовторение: модульная турельПовторение: спаренная пушка4Сериализованные данные
Сериализуемые классыСписки в инспектореПеречисления в инспектореПовторение: таблица добычиПовторение: определяем добычу2Интерфейсы в Unity
IDamageableИнтерфейсы и TryGetComponentGetComponentsПовторение: клавиша взаимодействияПовторение: ближайший в пределах досягаемости5ScriptableObjects
Ресурсы данныхХарактеристики оружияОбщие настройкиСохраняем ветерВолны как данныеПовторение: база предметовПовторение: покупка в магазинеПотренируйтесь самостоятельно: Песочница Unity