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

Creiamo il personaggio di un platform 2D

Iniziamo il percorso per creare un platform bidimensionale con Unity, assegnando un'immagine a uno Sprite e conferendogli degli attributi.
Iniziamo il percorso per creare un platform bidimensionale con Unity, assegnando un'immagine a uno Sprite e conferendogli degli attributi.
Link copiato negli appunti

Nella precedente lezione abbiamo visto come assegnare un semplice comportamento a un oggetto, come potrebbe essere un cubo. In questa lezione invece scopriremo come far sì che il giocatore possa muovere un GameObject e spostarlo in avanti e indietro, un comportamento che è ovviamente la base di ogni videogioco.

Come creare uno sprite

Figura 1. (click per ingrandire)


Figura 2. (click per ingrandire)


Anche in questo caso, creiamo un nuovo oggetto nella scena, partendo dal menu Game Object. Questa volta, però, selezioneremo 2D Object, Sprite. Come possiamo vedere, tuttavia, lo Sprite non si porta appresso un elemento grafico: dovremo collocarlo noi. Muoviamoci quindi nella parte inferiore dello schermo, nella tab Assets, dove sono raccolti tutti gli elementi collegati al nostro progetto (sebbene non siano necessariamente già presenti nella scena). Facciamo click destro su un punto qualsiasi della tab e clicchiamo su Import New Asset. Questa funzione ci sarà utile ogni qual volta vogliamo inserire dei file nel nostro progetto, siano essi immagini, suoni, script, etc.. Nel nostro esempio, abbiamo importato un file PNG di piccole dimensioni, come potrebbe essere un qualunque protagonista di un platform bidimensionale.

Figura 3. (click per ingrandire)


Figura 4. (click per ingrandire)


Per trasformare il nostro PNG in uno Sprite, dobbiamo innanzitutto farlo rientrare in tale categoria. Per riuscirci, clicchiamo sul personaggino nella tab Assets e nell'Inspector, alla voce Texture Type selezioniamo dal menu a tendina Sprite (2D and UI). A questo punto, nella Hierarchy clicchiamo su New Sprite; nell'Inspector troveremo una tab chiamata Sprite Renderer. La casella Sprite è inizialmente settata su None (Sprite). A destra della casella si trova un piccolo pallino, con un punto al centro: cliccandoci sopra si apre il menu Select Sprite, che attinge dal menu Assets. Clicchiamo sul nostro PNG e avremo il nostro personaggio in-game. Avremmo anche potuto, più velocemente, prendere il personaggio dalla tab Assets e trascinarlo tramite drag and drop sulla casella Sprite, a patto ovviamente di avergli assegnato la Texture Type Sprite (2D and UI).

Figura 5. (click per ingrandire)


Ora provate ad accedere alla Game Mode. Se non vedete il vostro personaggio, provate ad aggiustare i parametri della telecamera nella tabella Inspector, e nella fattispecie il suo asse Z, che per visualizzare il personaggio dev'essere di un valore superiore rispetto a quello dello sprite. Sempre nella tabella Inspector possiamo giocare con i parametri della telecamera, per esempio aumentando la dimensione dell'inquadratura, modificando il valore presente in Size. Abbiamo scelto, per questo esperimento, un valore pari a 4.

Lo script PlayerController

Figura 6. (click per ingrandire)


Come facciamo ora a muovere il personaggio? Anche in questo caso ci vengono in soccorso i Component. Clicchiamo sullo Sprite, e poi su Add Component. Invece di usare un elemento prefatto, tuttavia, sceglieremo Add New Script. Apparirà quindi un nuovo Component, di tipologia script (codice). Per riempirlo dobbiamo cliccare sull'icona a forma di ingranaggio alla destra del nome dello script, aprendo così Visual Studio, l'IDE (ambiente di sviluppo) diventato ormai standard di Unity, rimpiazzando MonoDevelop.

Figura 7. (click per ingrandire)


PlayerController deve essere assegnato a un oggetto, e nella fattispecie al nostro personaggio, che vediamo nella scena. Abbiamo anche un altro modo per creare questo script: cliccare con il destro nella finestra Assets, poi su Create, C# Script; a quel punto, si aprirà Visual Studio e potremo incollare il codice qui seguente. In alternativa, possiamo cliccare sul personaggio e, nell'Inspector, cliccare su Add Component, e successivamente su New Script. Clicchiamo sulla rotellina e si aprirà Visual Studio. Due modi diversi di fare la stessa cosa, come spesso capita in informatica. Ecco qui lo snippet, tratto dalla documentazione ufficiale di Unity, che dobbiamo usare per assegnare un sistema di movimento e controllo al personaggio:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerPlatformerController: PhysicsObject {
  public float maxSpeed = 7;
  public float jumpTakeOffSpeed = 7;
  private SpriteRenderer spriteRenderer;
  private Animator animator;
  // Use this for initialization
  void Awake() {
    spriteRenderer = GetComponent();
    animator = GetComponent();
  }
  protected override void ComputeVelocity() {
    Vector2 move = Vector2.zero;
    move.x = Input.GetAxis("Horizontal");
    if (Input.GetButtonDown("Jump") & amp; & amp; grounded) {
      velocity.y = jumpTakeOffSpeed;
    } else if (Input.GetButtonUp("Jump")) {
      if (velocity.y & gt; 0) {
        velocity.y = velocity.y * 0.5f;
      }
    }
    bool flipSprite = (spriteRenderer.flipX ? (move.x & gt; 0.01f) : (move.x & lt; 0.01f));
    if (flipSprite) {
      spriteRenderer.flipX = !spriteRenderer.flipX;
    }
    animator.SetBool("grounded", grounded);
    animator.SetFloat("velocityX", Mathf.Abs(velocity.x) / maxSpeed);
    targetVelocity = move * maxSpeed;
  }
}

Come creare un semplice sistema di fisica

Il secondo script, che chiameremo PhysicsObject, serve a determinare la fisica del gioco, ossia il modo in cui l'ambiente si comporterà, determinando di conseguenza la risposta del nostro personaggio principale. Per fare un esempio con l'universo reale, la fisica lunare prevede una gravità molto più bassa rispetto a quella del pianeta Terra, motivo per cui gli astronauti si muovono sul suolo del nostro satellite in quella maniera tanto particolare resa famosa da trasmissioni NASA e pellicole cinematografiche. Pensate quindi a un videogioco come un pianeta a parte, dove possiamo determinare noi le leggi della fisica. Perché PhysicsObject abbia un effetto sul gioco, è sufficiente che sia presente negli Assets; i suoi dati saranno richiamati, infatti, da altri script.

//Script PhysicsObject
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PhysicsObject: MonoBehaviour {
  public float minGroundNormalY = .65f;
  public float gravityModifier = 1f;
  protected Vector2 targetVelocity;
  protected bool grounded;
  protected Vector2 groundNormal;
  protected Rigidbody2D rb2d;
  protected Vector2 velocity;
  protected ContactFilter2D contactFilter;
  protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
  protected List hitBufferList = new List(16);
  protected const float minMoveDistance = 0.001f;
  protected const float shellRadius = 0.01f;
  void OnEnable() {
    rb2d = GetComponent();
  }
  void Start() {
    contactFilter.useTriggers = false;
    contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
    contactFilter.useLayerMask = true;
  }
  void Update() {
    targetVelocity = Vector2.zero;
    ComputeVelocity();
  }
  protected virtual void ComputeVelocity() {
  }
  void FixedUpdate() {
    velocity += gravityModifier * Physics2D.gravity * Time.deltaTime;
    velocity.x = targetVelocity.x;
    grounded = false;
    Vector2 deltaPosition = velocity * Time.deltaTime;
    Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
    Vector2 move = moveAlongGround * deltaPosition.x;
    Movement(move, false);
    move = Vector2.up * deltaPosition.y;
    Movement(move, true);
  }
  void Movement(Vector2 move, bool yMovement) {
    float distance = move.magnitude;
    if (distance & gt; minMoveDistance) {
      int count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
      hitBufferList.Clear();
      for (int i = 0; i & lt; count; i++) {
        hitBufferList.Add(hitBuffer[i]);
      }
      for (int i = 0; i minGroundNormalY) {
        grounded = true;
        if (yMovement) {
          groundNormal = currentNormal;
          currentNormal.x = 0;
        }
      }
      float projection = Vector2.Dot(velocity, currentNormal);
      if (projection & lt; 0) {
        velocity = velocity - projection * currentNormal;
      }
      float modifiedDistance = hitBufferList[i].distance - shellRadius;
      distance = modifiedDistance & lt;
      distance ? modifiedDistance: distance;
    }
    rb2d.position = rb2d.position + move.normalized * distance;
  }
}

Perché il nostro personaggio cammini, tuttavia, mancano ancora alcuni elementi. Innanzitutto, dobbiamo assegnargli un componente che lo rende sollecitabile rispetto alla fisica, ossia Rigidbody 2D; ancora una volta, il procedimento è lo stesso: Add Component, e ricerchiamo il nome di questo componente. Non è finita qui: dobbiamo aggiungergli anche un component Box Collider 2D, che calcolerà le collisioni con il resto dello scenario. Per l'esempio, aggiungiamo anche un component Animator, che gestisce le animazioni del nostro personaggio (la camminata, il salto, etc.); sono solo un elemento grafico che non influisce sul funzionamento delle meccaniche, ma lo script che abbiamo usate fa riferimento all'Animator, per cui se non lo inseriamo riceveremo un messaggio d'errore. In seguito, vedremo come impostare le diverse animazioni del personaggio. A questo punto, manca soltanto una piattaforma, che impedirà al nostro personaggio di cadere nel vuoto. Creiamo un semplice Cube, usando GameObject, 3D Object, Cube e assegniamogli un component Box Collider 2D. Clicchiamo su Play e potremo controllare la camminata del nostro personaggio sulla piattaforma, usando i tasti WASD o i direzionali; con la spaziatrice invece potremo farlo saltare.

Figura 8. (click per ingrandire)


Nello script che abbiamo usato il salto è piuttosto contenuto; possiamo giocare con i parametri aumentando il valore di Jump Take Off Speed: alzandolo di poche unità, il salto del personaggio sarà decisamente più in alto. Se invece vogliamo aumentare la velocità del nostro personaggio, impostiamo un valore più alto per la Max Speed. Possiamo impostare questi parametri perché il codice è strutturato in maniera tale da poterli editare tramite interfaccia, ma questa è una decisione che possiamo prendere quando scriviamo, appunto, il codice.

Ti consigliamo anche