Boss Fight
Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 64 of 64.
A stone golem guards the gate out of the arena. It stomps toward you, and when you come close it raises its fists for a second and slams the ground, which hurts you if you are still near. After a slam it rests, and only then can your sword hurt it: its stone skin shrugs off every hit while it walks or winds up. Its color says what it is doing: gray as it walks, red as it winds up, cyan as it rests. Bring its health to 0 and the gate opens. The bar at the top of the screen follows every hit.
Write the golem's brain as a state machine with a class for each state: Boss, and ChaseState, WindupState and RestState in BossStates.cs. The player, the health bar, the gate, IState, StateMachine and IDamageable are ready, and Boss already makes its states and ticks the machine.
Challenge
HardWrite the golem's states in BossStates.cs.
ChaseState:Tint(Color.gray); walk at the player atspeed; withinslamRange, wind up.WindupState:Tint(Color.red); afterwindupTime, logSlam!, hurt a player in range byslamDamage, rest.RestState:Tint(Color.cyan); afterrestTime, chase.Boss.TakeDamagecounts only inrest: take the amount, raiseHealthChanged,Fall()at 0.
Press Play and strike while it rests. Then Check.
Try it yourself
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)
{
// Hits count only while it rests: take the amount, raise HealthChanged, Fall() at 0
}
// Ready: the golem falls, the gate opens and the golem leaves the arena.
void Fall()
{
Debug.Log("The golem falls");
onDefeated.Invoke();
gameObject.SetActive(false);
}
// How far the player is, across the ground.
public float PlayerDistance()
{
Vector3 d = player.position - transform.position;
d.y = 0f;
return d.magnitude;
}
// Gray while it walks, red while it winds up, cyan while it rests.
public void Tint(Color color)
{
GetComponent<Renderer>().material.color = color;
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Game Architecture in Unity
1Components, Not Hierarchies
Small ComponentsA Base Enemy ScriptAbstract ComponentsComponents Working TogetherRecap: Modular TurretRecap: Twin Cannon4Serialized Data
Serializable ClassesLists in the InspectorEnums in the InspectorRecap: Loot TableRecap: Roll the Loot2Interfaces in Unity
IDamageableInterfaces and TryGetComponentGetComponentsRecap: Interact KeyRecap: Nearest in ReachPractice on your own: Unity playground