Struttura dell'unità di gioco RTS


18

Voglio un modo per creare molte unità diverse senza dover programmare cose come moveTo e Attack più di una volta

Per come la vedo io, ci sono 2 modi in cui posso farlo.

  1. Una singola classe di unità generica con flag che specifica cosa può / non può fare (quindi creare istanze in un array statico e acquisirle quando necessario)
  2. Classe di unità astratta con metodi astratti per azioni specifiche dell'unità come (Attacco, Raccolto, Pattuglia), che quindi devono essere implementate tutte nelle sottoclassi , anche se l'unità non può effettivamente raccogliere nulla.

il primo modo per farlo sembra il più semplice, ma finirei per avere un sacco di codice inutilizzato per la maggior parte delle unità.

il secondo modo potrebbe anche funzionare. Ma se decido di avere due unità diverse in grado di raccogliere risorse, avrò lo stesso codice esatto in due classi diverse, che non sembra il modo giusto per farlo.

È forse questo l'approccio giusto a questo problema?
In un gioco come AoE, ogni unità ha, quello che presumo sia, una specie di Elenco di Azioni / Ordini, Mi piacerebbe davvero sapere come ottenere qualcosa di simile a quello, dove posso semplicemente codificare ogni Azione / Ordine una volta, e quindi dallo a tutte le unità che necessitano di detta Azione.

Se non sono chiaro (altamente plausibile) o hai bisogno di maggiori informazioni su cosa sto esattamente cercando, chiedimi in un commento.

Risposte:


25

Un approccio comune è quello di avere un approccio basato sui componenti in cui la "Base" di classe base implementa solo gli aspetti più basilari che tutte le unità hanno in comune, mentre ogni unità ha quindi un elenco di più oggetti componente che dicono cosa può fare e come lo fa.

Ad esempio, un serbatoio può avere componenti Mobile, Destructible, Attacker, un immobile torretta unico Destructible, Attackere una mietitrice Mobile, Destructible, Harvester. Queste classi includeranno quindi tutto il codice necessario per implementare questi comportamenti. Le interazioni tra i componenti ( Attackerpossono solo danneggiare ciò che è Destructible) possono essere implementate facendo controllare il componente se l'altra unità ha il componente richiesto e quindi interagire direttamente con quel componente.

Il vantaggio rispetto a un'eredità di classe classica è che puoi combinare facilmente le abilità. Ad esempio, quando vuoi avere una mietitrice che può anche attaccare, trasportare la fanteria e volare, devi solo aggiungere i componenti necessari. È inoltre possibile aggiungere e rimuovere facilmente nuove funzionalità sotto forma di nuovi componenti senza dover gonfiare la classe di unità di base.

Unity ti supporta in tale architettura, perché l'intero motore è già basato su componenti. Quindi componenti logici di gioco come questi possono essere aggiunti sotto forma di script.


Quindi, in unità, disabiliterei e abiliterei i componenti secondo necessità ?.
Daniel Holst,

@DanielHolst No, dovresti aggiungerli e rimuoverli se necessario. Puoi farlo nell'editor Unity o con gli script usando gameObject.AddComponente gameObject.RemoveComponent.
Philipp

ah va bene, ma dì per un'azione / ordine "moveTo". come farebbe l'unità a sapere quando viene eseguito l'ordine? e come farei la coda degli ordini?
Daniel Holst,

2
@DanielHolst Penso che tu abbia frainteso qualcosa. Il Movingcomponente significa "questa unità è generalmente in grado di muoversi". Il componente è fissato in modo permanente ad esso, indipendentemente dal fatto che l'unità si stia muovendo o meno. Non significa che si stia muovendo proprio ora . Anche se si potrebbe anche fare in questo modo con l'aggiunta di un MoveOrdercomponente ad esso e avere che rimuovono componente stesso dall'unità quando l'ordine è adempiuta o cancellata.
Philipp,

1
@DanielHolst Ora stai andando alla direzione dell'unità AI, che è tutta un'altra lattina di vermi. Un possibile approccio sarebbe quello di avere una libreria di componenti AIScript che presumono che alcuni componenti siano presenti o cambiano il loro comportamento a seconda di quali componenti sta avendo l'unità. Ma questo è davvero un argomento troppo complesso da gestire in un commento.
Philipp,

4

Molti giochi usano un sistema basato su componenti per entità in cui è possibile aggiungere un gruppo di comportamenti e abilità a un tipo di unità più generico anziché essere codificato come parte della classe dell'entità (o equivalente).


sarebbe estremamente difficile da implementare?
Daniel Holst,

Modelli come questo sono usati per rendere l'implementazione più semplice nel complesso. Se non riesci a decidere quale approccio adottare, è una buona idea iniziare nel modo più semplice possibile e ampliare la tua scelta man mano che ti trovi in ​​più funzionalità. Una volta che hai più un'idea del problema, puoi rifattorizzare o riscrivere un approccio che si adatti meglio alla tua situazione.
Ross Taylor-Turner,

1
@DanielHolst Ho notato che la tua domanda ha la Unitybandiera. Unity ha già un sistema di componenti integrato e favorisce fortemente la composizione rispetto all'eredità . Un metodo semplice sarebbe quello di creare un MonoBehaviourper ciascuno dei tuoi tipi di azione, quindi collegare a ciascun tipo di unità prefabbricato le azioni che è in grado di eseguire (personalizzando le istanze di azione con dettagli per tipo come valori di danno e costi). Ciò mantiene la creazione dell'unità basata sui dati, in modo da poter creare facilmente molti tipi di unità personalizzati.
DMGregory

@DanielHolst Dipende dalla tua definizione di "estremamente difficile". La mia risposta è più dettagliata su come potrebbe essere implementata.
Philipp,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.