Intelligenza dei nemici
Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 39 di 64.
Il cervello di un nemico è una macchina a stati con uno stato per ogni comportamento. Questo scheletro cammina tra i suoi posti di guardia, insegue un giocatore che si avvicina entro 6 unità e sferra un colpo di spada una volta al secondo quando è vicino. Ogni stato decide da sé come uscirne, e lo scheletro mantiene gli helper che condividono:
public class Skeleton : MonoBehaviour
{
public Transform player;
public Transform[] posts;
public float speed = 2f;
public StateMachine machine = new StateMachine();
public IState patrol, chase, attack;
void Start()
{
patrol = new PatrolState(this);
chase = new ChaseState(this);
attack = new AttackState(this);
machine.ChangeState(patrol);
}
void Update() { machine.Tick(); }
public float PlayerDistance() { return Vector3.Distance(transform.position, player.position); }
public void WalkTo(Vector3 target)
{
target.y = transform.position.y;
transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
}
public class PatrolState : IState
{
private Skeleton skel;
private int next;
public PatrolState(Skeleton skel) { this.skel = skel; }
public void Enter() { }
public void Exit() { }
public void Tick()
{
if (skel.PlayerDistance() < 6f) { skel.machine.ChangeState(skel.chase); return; }
Vector3 post = skel.posts[next].position;
post.y = skel.transform.position.y;
skel.WalkTo(post);
if (skel.transform.position == post) next = (next + 1) % skel.posts.Length;
}
}
public class ChaseState : IState
{
private Skeleton skel;
public ChaseState(Skeleton skel) { this.skel = skel; }
public void Enter() { }
public void Exit() { }
public void Tick()
{
float d = skel.PlayerDistance();
if (d > 6f) { skel.machine.ChangeState(skel.patrol); return; }
if (d < 1.5f) { skel.machine.ChangeState(skel.attack); return; }
skel.WalkTo(skel.player.position);
}
}
public class AttackState : IState
{
private Skeleton skel;
private float cooldown;
public AttackState(Skeleton skel) { this.skel = skel; }
public void Enter() { cooldown = 0f; }
public void Exit() { }
public void Tick()
{
if (skel.PlayerDistance() > 1.5f) { skel.machine.ChangeState(skel.chase); return; }
cooldown -= Time.deltaTime;
if (cooldown <= 0f) { Debug.Log("Swing!"); cooldown = 1f; }
}
}Gli stati vengono creati una sola volta e restano in vita quanto lo scheletro, quindi i loro campi persistono tra una visita e l'altra. next di PatrolState mantiene il suo valore anche dopo un inseguimento, e lo scheletro continua a camminare verso il posto di guardia che stava raggiungendo. Enter reimposta solo ciò che deve ripartire da zero: quello di AttackState imposta cooldown a 0, così il primo colpo arriva non appena lo scheletro raggiunge il giocatore.
Tutti gli spostamenti passano per WalkTo, qui MoveTowards sul transform, che attraversa i muri. Per spostare lo scheletro con un Rigidbody, invece, WalkTo imposta la velocità del corpo e lo scheletro aggiorna la macchina in FixedUpdate, dove Time.deltaTime è il passo della fisica. I tre stati non cambiano: indicano dove andare, mentre il proprietario indica come.
Sfida
MedioAssegna al cavaliere PatrolState e ChaseState in KnightStates.cs, fornendo a ciascuno il cavaliere.
- Pattuglia: cammina verso
waypoints[next]; quando sei a meno di0.3, incrementanextin modo circolare e mantienilo tra una visita e l’altra. Se è più vicino disightRange, inseguilo. - Inseguimento: cammina verso il giocatore; se è più lontano di
loseRange, torna a pattugliare. - In
Knight, crea la macchina e gli stati in Awake, avvia la pattuglia in Start e richiama Tick in FixedUpdate.
Premi «Gioca», poi avvicinati e scappa. Poi premi «Verifica».
Provalo tu
using UnityEngine;
// PatrolState e ChaseState
Tutte le lezioni di Architettura dei giochi in Unity
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRipasso: torretta modulareRipasso: cannone doppio4Dati serializzati
Classi serializzabiliElenchi nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottinoRiepilogo: tira il bottino7Macchine a stati
Gli stati come classiLo stato di allertaUna macchina a statiTransizioniIntelligenza dei nemiciIl cavaliere attaccaRiepilogo: stati delle porte2Interfacce in Unity
IDamageableInterfacce e TryGetComponentGetComponentsRiepilogo: tasto InteragisciRiepilogo: il più vicino a portata5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseSalva il ventoOnde come datiRiepilogo: database degli oggettiRiepilogo: comprare dal negozioEsercitati da solo: Playground Unity