Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 22 di 31
  • livello principiante
Indice lezioni

Creare un nemico che si muove e un proiettile che lo colpisce

In questa lezione creeremo prima un nemico che si muove orizzontalmente, e poi un proiettile ed un sistema di salute per gestirne la vita.
In questa lezione creeremo prima un nemico che si muove orizzontalmente, e poi un proiettile ed un sistema di salute per gestirne la vita.
Link copiato negli appunti

Che cosa sarebbe un platform senza un nemico? Per introdurre degli avversari all’interno del nostro platform, andremo quindi a creare innanzitutto un’entità con una semplicissima intelligenza artificiale, che ne detterà i movimenti lungo il livello. Poi, determineremo il modo in cui il giocatore può sparare una palla di fuoco al nemico, e come il gioco calcolerà il danno, decretando quindi la fine del nostro nemico. Come al solito, il cattivone di questo livello andrà creato importando uno sprite all’interno della scena, e attribuendogli dei Component che determinerà il modo in cui interagisce con l’ambiente: BoxCollider2D e Rigidbody2D, assicurandoci in quest’ultimo caso che la Gravity Scale sia impostata a 0.

Figura 1. (click per ingrandire)


A questo punto, creiamo un nuovo script cliccando su Create, C# Script nella finestra degli Asset e chiamiamolo EnemyScript. Come al solito, entriamo in Visual Studio per modificarlo, e introduciamo il seguente codice:

using UnityEngine;
 
public class EnemyScript: MonoBehaviour {
  // 1 - Designer variables
  /// La velocità dell’oggetto.
  public Vector2 speed = new Vector2(10, 10);
 
  /// La direzione in cui si muove l’oggetto
  public Vector2 direction = new Vector2( - 1, 0);
 
  private Vector2 movement;
  private Rigidbody2D rigidbodyComponent;
 
  void Update() {
    // Il movimento, che risulta dal rapporto tra velocità e direzione.
    movement = new Vector2(
    speed.x * direction.x, speed.y * direction.y);
  }
 
  void FixedUpdate() {
    if (rigidbodyComponent == null) rigidbodyComponent = GetComponent();
 
    // Questo serve ad applicare la velocità al Rigidbody.
    rigidbodyComponent.velocity = movement;
  }
}

A questo punto, assegniamo lo script al nostro nemico e, come da codice, questo si comporterà muovendosi verso sinistra, a una velocità che possiamo impostare a piacimento, dal momento che la variabile Speed è esposta e pubblica. Lasciare esposte queste variabili è importantissimo, perché così permetteremo ai game designer e ai level designer di gestire i diversi parametri, senza che debbano muoversi all’interno dell’editor degli script e programmare. Abbiamo quindi ridotto la velocità a 5, che è più meno la velocità con cui si muove un Goomba in Super Mario Bros.. Come possiamo vedere nel codice, abbiamo usato una variabile chiamata Vector2, ossia un’informazione che racchiude l’insieme di un numero reale positivo, una direzione e un verso. Vector2 viene chiaramente usato per i videogiochi 2D, laddove in un videogioco 3D avremmo usato Vector3, che ci permette di impostare anche la profondità.

Come creare un proiettile che colpisce il nemico

Al momento il nemico verrà semplicemente verso la nostra direzione, solo che non avremo modo di difenderci (non sarebbe comunque un problema perché al momento la nostra gelatina è innocua, in quanto non abbiamo impostato quello che succede quando collide con il nemico, né un sistema di salute). Ci sono vari modi per far sì che il nostro protagonista colpisca un nemico, nel nostro caso abbiamo deciso di assegnargli un proiettile, una palla di fuoco, che andrà contro il nemico e gli sottrarrà energia, sconfiggendolo. Creiamo sempre uno sprite che chiameremo fireball, assegniamogli Box Collider 2D e Rigidbody 2D con Gravity Scale a 0. Nell’Inspector, alla voce Box Collider 2D, spuntiamo Is Trigger. Questa opzione permette di far verificare degli eventi al momento della collisione, ma non produce alcun cambiamento pratico dal punto di vista fisico.

Figura 2. (click per ingrandire)


Il codice per la palla di fuoco, che assegneremo al nostro sprite, è il seguente. Lo chiameremo ShootFireball:

using UnityEngine;
 
/// Queste sono le dinamiche del proiettile.
public class ShootFireball: MonoBehaviour {
  // 1 - Designer variables
  /// Il danno che viene inflitto dal proiettile.
  public int damage = 1;
 
  /// Con questa booleana decidiamo se il proiettile
  /// danneggia il personaggio o il nemico.
  public bool isEnemyShot = false;
 
  void Start() {
    // Distruggiamo il proiettile dopo qualche secondo che viene usato.
    Destroy(gameObject, 20); // 20 secondi.
  }
}

Come creare un sistema di salute

Assegniamo EnemyScript al proiettile, altrimenti non si muoverà, e impostiamo la X di Direction a 1. Osserviamo ora come, premendo Play, il proiettile va effettivamente contro il nemico, ma non succede niente, pur avendo impostato tra i valori una quantità di danno che viene arrecato. Ma il nostro nemico non ha alcuna variabile che decreta il suo livello di salute, per cui esso non può essere influenzato dal proiettile. Rimediamo subito con il seguente script, che chiameremo EnemyHealth:

using UnityEngine;
 
public class EnemyHealth: MonoBehaviour {
  /// Il numero dei punti vita del nemico
  public int hp = 1;
 
  /// Una booleana che determina se l’oggetto a cui è assegnato lo script sia il protagonista o un nemico.
  public bool isEnemy = true;
 
  /// Una variabile che causa il danno e verifica se il nemico dev’essere distrutto.
  public void Damage(int damageCount) {
    hp -= damageCount;
 
    if (hp & lt; = 0) {
      // Se I punti vita sono uguali o minori di 0, il nemico viene distrutto.
      Destroy(gameObject);
    }
  }
 
  void OnTriggerEnter2D(Collider2D otherCollider) {
    ShootFireball shot = otherCollider.gameObject.GetComponent();
    if (shot != null) {
      // Impedisce che il giocatore venga colpito.
      if (shot.isEnemyShot != isEnemy) {
        Damage(shot.damage);
      }
    }
  }
}

La variabile esposta di EnemyHealth è Hp, ossia i punti vita del personaggio, che possiamo modificare a piacimento. Ovviamente, più sono alti, più ci vorranno proiettili per abbassare lo stato di salute, a meno che ovviamente non rendiamo i proiettili più potenti. Sempre qui, spuntiamo la voce Is Enemy (mentre dobbiamo ricordarci che su Shoot Fireball non dobbiamo spuntare la casella Is Enemy Shot). Seguendo tutti i passaggi, ora avremo un proiettile che, quando colpisce la gelatina, la distrugge; immediatamente dopo, anche il proiettile viene distrutto.

Ti consigliamo anche