Crea un gioco di realtà aumentata in stile Pokémon GO con Vuforia parte 2

Cosa starai creando

Nell'ultimo post di questa serie, abbiamo imparato come impostare Vuforia e iniziare a sviluppare un gioco AR da zero, adottando una logica simile a quella utilizzata su Pokémon GO!

  • Crea un gioco di realtà aumentata in stile Pokémon GO con Vuforia

    In questo tutorial inizieremo a creare un'app con Augmented Reality utilizzando Vuforia su Unity 3D. Impareremo come impostare Vuforia e iniziare a sviluppare un AR ...
    Tin Megali
    Sviluppo mobile
  • Pokémon GO Style Realtà Aumentata con Vuforia

    Con il successo virale di Pokemon GO, tutti parlano di realtà aumentata. In questo tutorial vedremo come utilizzare Vuforia per la realtà aumentata ...
    Tin Megali
    Sviluppo mobile
  • Pokémon GO Style Realtà Aumentata: Markers

    Di recente, Pokémon Go ha conquistato il mondo. Una delle parti più interessanti e coinvolgenti di questo gioco è l'uso della realtà aumentata, o AR. AR è ...
    Derek Jensen
    App per dispositivi mobili

Abbiamo iniziato lo sviluppo di un gioco in Realtà Aumentata chiamato Shoot the Cubes. Ora è il momento di migliorare il gioco aggiungendo interazione e rendendo l'esperienza più coinvolgente. Ci concentreremo soprattutto sulle possibilità che Unity ci offre, tralasciando le specifiche di Vuforia. L'esperienza con il motore Unity non è obbligatoria.

1. Rendere vivi i cubi

Iniziamo a lavorare sul nostro gioco. Finora siamo riusciti a creare una scena in Realtà Aumentata che si muove con il dispositivo dell'utente. Miglioreremo questa app facendo spawnare e volare i cubi, e permettendo al giocatore di cercare e distruggerli con un colpo laser.

1.1. Generare gli elementi

Abbiamo già impostato una posizione iniziale del _SpawnController in base alla rotazione della fotocamera del dispositivo. Ora stabiliremo un'area intorno a questo punto in cui verranno generati i nostri cubi. Ora aggiorneremo il SpawnScript fare il _SpawnController istanziare gli elementi del cubo con diverse dimensioni e posizioni casuali, rispetto al _SpawnController.

Modifichiamo il SpawnScript classe, aggiungendo alcune variabili per controllare il processo di spawn.

classe pubblica SpawnScript: MonoBehaviour // Elemento cubo per generare pubblico GameObject mCubeObj; // Qtd di cubi da spawned public int mTotalCubes = 10; // Tempo di spawn del cubo public float mTimeToSpawn = 1f; // tieni tutti i cubi sul palco privato GameObject [] mCubes; // definisce se è stata impostata la posizione private bool mPositionSet; 

Creeremo una coroutine chiamata SpawnLoop per gestire il processo di spawn. Sarà anche responsabile di impostare la posizione iniziale del _SpawnController quando inizia il gioco. Si noti che il Random.insideUnitSphere il metodo fa sì che i cubi vengano istanziati in posizioni casuali all'interno di un'area sferica attorno al _SpawnManager.

public class SpawnScript: MonoBehaviour // Loop spawning cube elements private IEnumerator SpawnLoop () // Definizione della posizione di spawn StartCoroutine (ChangePosition ()); yield return new WaitForSeconds (0.2f); // spawning degli elementi int i = 0; mentre io <= (mTotalCubes-1) )  mCubes[i] = SpawnElement(); i++; yield return new WaitForSeconds(Random.Range(mTimeToSpawn, mTimeToSpawn*3));   // Spawn a cube private GameObject SpawnElement()  // spawn the element on a random position, inside a imaginary sphere GameObject cube = Instantiate(mCubeObj, (Random.insideUnitSphere*4) + transform.position, transform.rotation ) as GameObject; // define a random scale for the cube float scale = Random.Range(0.5f, 2f); // change the cube scale cube.transform.localScale = new Vector3( scale, scale, scale ); return cube;  

Infine, modifica il file Inizio() funzione. Assicurati di rimuovere il  StartCoroutine (ChangePosition ());  linea e sostituirlo con una chiamata per avviare il SpawnLoop coroutine.

public class SpawnScript: MonoBehaviour void Start () // Inizializzazione del ciclo di spawn StartCoroutine (SpawnLoop ()); // Inizializza l'array di cubi secondo // la quantità desiderata mCubes = new GameObject [mTotalCubes]; 

Ora di nuovo in Unity dovrai creare un prefabbricato cubo per essere istanziato dallo script. 

  • Crea una cartella chiamata prefabbricati nel Progetto finestra.
  • Cambiare il Cubo scala dell'elemento su tutti gli assi a 1 e cambia la rotazione in 0 su tutti gli assi.
  • Trascina il Cubo al prefabbricati cartella.
  • Elimina il cubo dal Gerarchia finestra.
  • Seleziona il _SpawnController e trascina il Cubo prefabbricato dal prefabbricati cartella al M Cube Obj campo, situato nel SpawnScript area dell'ispettore.


Infine, elimina il Sfera situato all'interno del _SpawnManager.

Ora, se premi play in Unity ed esegui il progetto sul dispositivo, dovresti vedere i cubi spawn.

1.2. Cubi rotanti

Abbiamo bisogno di aggiungere movimento a quei cubi per rendere le cose più interessanti. Ruotiamo i cubetti attorno ai loro assi e sopra il ARCamera. Sarebbe anche bello aggiungere un fattore casuale al movimento del cubo per creare un'atmosfera più organica.

Trascina il Cubo Prefabbricato dal prefabbricati cartella nella gerarchia.

  • Sul Script cartella crea un nuovo C # Script chiamato CubeBehaviorScript.
  • Trascina lo script su Cubo prefabbricato e aprilo per modificare.

Ogni cubo avrà caratteristiche casuali. La dimensione, la velocità di rotazione e la direzione di rotazione saranno definite casualmente, utilizzando alcuni riferimenti precedentemente definiti. Creiamo alcune variabili del controller e inizializziamo lo stato del cubo.

usando UnityEngine; usando System.Collections; public class CubeBehaviorScript: MonoBehaviour // Cube's Max / Min scale float pubblico mScaleMax = 2f; public float mScaleMin = 0.5f; // Orbit max Speed ​​public float mOrbitMaxSpeed ​​= 30f; // Orbit speed private float mOrbitSpeed; // Punto di ancoraggio per il cubo per ruotare attorno alla trasformazione privata mOrbitAnchor; // Orbita in direzione privata Vector3 mOrbitDirection; // Max Cube Scale private Vector3 mCubeMaxScale; // Growing Speed ​​public float mGrowingSpeed ​​= 10f; private bool mIsCubeScaled = false; void Start () CubeSettings ();  // Imposta le impostazioni del cubo iniziale private void CubeSettings () // definisce il punto di ancoraggio come camera principale mOrbitAnchor = Camera.main.transform; // definisce la direzione dell'orbita float x = Random.Range (-1f, 1f); float y = Random.Range (-1f, 1f); float z = Random.Range (-1f, 1f); mOrbitDirection = new Vector3 (x, y, z); // definizione della velocità mOrbitSpeed ​​= Random.Range (5f, mOrbitMaxSpeed); // defining scale float scale = Random.Range (mScaleMin, mScaleMax); mCubeMaxScale = new Vector3 (scala, scala, scala); // imposta la scala del cubo a 0, per accrescerla cancella transform.localScale = Vector3.zero; 

Ora è il momento di aggiungere qualche movimento al nostro cubo. Facciamolo ruotare su se stesso e intorno al ARCamera, utilizzando la velocità e la direzione casuali definite in precedenza.

 // L'aggiornamento viene chiamato una volta per ogni frame void Update () // rende l'orbita del cubo e ruota RotateCube ();  // Fa ruotare il cubo attorno a un punto di ancoraggio // e ruota attorno al proprio asse. Vuoto privato RotateCube () // ruota attorno alla telecamera transform.RotateAround (mOrbitAnchor.position, mOrbitDirection, mOrbitSpeed ​​* Time.deltaTime); // ruota attorno al suo asse transform.Rotate (mOrbitDirection * 30 * Time.deltaTime); 

Per renderlo più organico, il cubo si scalerà dalla dimensione zero dopo che è stato generato.

 // L'aggiornamento viene chiamato una volta per ogni frame void Update () // rende l'orbita del cubo e ruota RotateCube (); // ridimensiona cubo se necessario se (! mIsCubeScaled) ScaleObj ();  // Scala oggetto da 0 a 1 privato vuoto ScaleObj () // crescente obj if (transform.localScale! = MCubeMaxScale) transform.localScale = Vector3.Lerp (transform.localScale, mCubeMaxScale, Time.deltaTime * mGrowingSpeed); else mIsCubeScaled = true; 

2. Ricerca e distruzione

Quei cubi sono troppo felici che volano in giro in quel modo. Dobbiamo distruggerli con i laser! Creiamo una pistola nel nostro gioco e iniziamo a sparare.

2.1. Scatto di un laser

Il colpo laser deve essere collegato al ARCamera e la sua rotazione. Ogni volta che il giocatore "tocca" lo schermo del dispositivo, verrà sparato un laser. Useremo il Physics.Raycast classe per verificare se il laser colpisce il bersaglio e in tal caso toglieremo un po 'di salute da esso.

  • Crea un nuovo oggetto vuoto chiamato _PlayerController e un altro oggetto vuoto chiamato _LaserController dentro di esso. 
  • Aggiungere un Script C # chiamato LaserScript dentro il Script cartella e trascinarlo _LaserController.

Dentro LaserScript, useremo a LineRenderer per mostrare il raggio laser, utilizzando un punto di origine collegato al fondo del ARCamera. Per ottenere il punto di origine del raggio laser, la canna della pistola virtuale, otterremo la fotocamera Trasformare nel momento in cui viene sparato un laser e spostarlo di 10 unità verso il basso. 

Innanzitutto, creiamo alcune variabili per controllare le impostazioni del laser e ottenere mLaserLine.

usando UnityEngine; usando System.Collections; classe pubblica LaserScript: MonoBehaviour public float mFireRate = .5f; public float mFireRange = 50f; public float mHitForce = 100f; public int mLaserDamage = 100; // Line render che rappresenterà il Laser LineRenderer privato mLaserLine; // Definire se la linea laser mostra bool privato mLaserLineEnabled; // Tempo in cui le linee Laser mostrano WaitForSeconds privato sullo schermo mLaserDuration = new WaitForSeconds (0.05f); // ora del prossimo incendio privato float mNextFire; // Usa questo per l'inizializzazione void Start () // ottenendo il Line Renderer mLaserLine = GetComponent();  

La funzione responsabile per lo scatto è Fuoco(). Questo sarà chiamato ogni volta che il giocatore preme il pulsante di fuoco. Notare che Camera.main.transform viene utilizzato per ottenere il ARCamera posizione e rotazione e che il laser è posizionato a 10 unità al di sotto di quello. Questo posiziona il laser nella parte inferiore della fotocamera.

// Shot the Laser private void Fire () // Get ARCamera Transform Transform cam = Camera.main.transform; // Definisci il tempo del prossimo incendio mNextFire = Time.time + mFireRate; // Imposta l'origine di RayCast Vector3 rayOrigin = cam.position; // Imposta la posizione di origine della linea laser // Sarà sempre 10 unità in giù dalla ARCamera // Abbiamo adottato questa logica per semplicità mLaserLine.SetPosition (0, transform.up * -10f); 

Per verificare se il bersaglio è stato colpito, useremo a raycast.

// Shot the Laser private void Fire () // Tieni premuto il hit Hit di RaycastHit; // Controlla se RayCast ha colpito qualcosa se (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Imposta la fine della linea laser sull'oggetto hit mLaserLine.SetPosition (1, hit.point) ;  else // Imposta l'enfo della linea laser per far avanzare la telecamera // usando la gamma Laser mLaserLine.SetPosition (1, cam.forward * mFireRange); 

Alla fine, è tempo di controllare se il pulsante di fuoco è stato premuto e chiamare gli effetti del laser quando viene sparato il colpo.

// L'aggiornamento viene chiamato una volta per frame void Update () if (Input.GetButton ("Fire1") && Time.time> mNextFire) Fire ();  private void Fire () // codice anteriore soppresso per semplicità // Mostra il laser usando una Coroutine StartCoroutine (LaserFx ());  // Mostra gli effetti laser IEnumerator private LaserFx () mLaserLine.enabled = true; // Via per un tempo specifico per rimuovere il ritorno rendimento di LineRenderer mLaserDuration; mLaserLine.enabled = false; 

Tornando a Unity dovremo aggiungere un LineRenderer componente al _LaserController oggetto.

  • Selezionare _LaserController e nel Ispettore finestra, fare clic su Aggiungi componente. Nominalo "Line Renderer"e selezionare il nuovo componente.
  • Crea una nuova cartella chiamata materiale, e creare un nuovo materiale all'interno di esso chiamato Laser.
  • Seleziona il Laser materiale e cambiarlo in qualsiasi colore che ti piace.
  • Seleziona il _LaserController e trascina il materiale Laser su materiale campo del LineRenderer componente.
  • Ancora dentro LineRenderer, sotto parametri impostato Iniziare con a 1 e Fine Con a 0.

Se testi il ​​gioco ora dovresti vedere un laser sparato dalla parte inferiore dello schermo. Sentiti libero di aggiungere un Sorgente Audio componente con un effetto sonoro laser a _LaserController per ravvivarlo.

2.1. Colpire i cubi

I nostri laser devono colpire i loro bersagli, applicare i danni e infine distruggere i cubi. Dovremo aggiungere un Corpo rigido ai cubi, applicando forza e danno a loro.

  • Trascinare il Cubo prefabbricato dalla cartella prefabbricati a qualsiasi posto sul Palcoscenico.
  • Selezionare il Cubo e selezionare Aggiungi componente nelil Ispettore finestra. Assegna un nome al nuovo componente "Corpo rigido"e selezionalo.
  • Sul Corpo rigido set di componenti Gravità e È cinematico a via.
  • Applica queste modifiche al prefabbricato.

Ora modifichiamo il CubeBehavior script per creare una funzione responsabile dell'applicazione del danno al cubo e un altro per distruggerlo quando la salute scende al di sotto di 0.

public class CubeBehaviorScript: MonoBehaviour // Cube Health public int mCubeHealth = 100; // Definisci se il cubo è vivo. Bool privato mIsAlive = true; // Cube ha ottenuto Hit // restituisce 'false' quando il cubo è stato distrutto public bool Hit (int hitDamage) mCubeHealth - = hitDamage; if (mCubeHealth> = 0 && mIsAlive) StartCoroutine (DestroyCube ()); ritorna vero;  return false;  // Destroy Cube private IEnumerator DestroyCube () mIsAlive = false; // Fa in modo che il cubo scompaia GetComponent() .enabled = false; // aspetteremo un po 'di tempo prima di distruggere l'elemento // questo è utile quando si usa qualche tipo di effetto // come un effetto sonoro esplosivo. // in questo caso potremmo usare la lunghezza del suono come attesa return return new WaitForSeconds (0.5f); Destroy (gameObject); 

Ok, il cubo può ora subire danni e essere distrutto. Modifichiamo il LaserScript per applicare danni al cubo. Tutto quello che dobbiamo fare è cambiare il Fuoco() funzione per chiamare il  Colpire metodo del CubeBehavior copione.

public class LaserScript: MonoBehaviour // Shot the Laser private void Fire () // codice soppresso per semplicità ... // Controlla se RayCast ha colpito qualcosa se (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Imposta la fine della linea laser sull'oggetto colpito mLaserLine.SetPosition (1, hit.point); // Ottieni lo script CubeBehavior per applicare il danno al target CubeBehaviorScript cubeCtr = hit.collider.GetComponent(); if (cubeCtr! = null) if (hit.rigidbody! = null) // applica la forza al target hit.rigidbody.AddForce (-hit.normal * mHitForce); // applica il danno al target cubeCtr.Hit (mLaserDamage); 

3. Conclusione

Congratulazioni! Il nostro gioco in Realtà Aumentata è finito! Sì, il gioco potrebbe essere più lucido, ma le basi sono lì e l'esperienza complessiva è piuttosto coinvolgente. Per renderlo più interessante potresti aggiungere un'esplosione di particelle, come quella che ho fatto nel video, e per di più potresti aggiungere un sistema di punteggio o anche un sistema a onde con un timer per renderlo più di una sfida. I prossimi passi dipendono da te!

3.1. Qual'è il prossimo?

Abbiamo creato un esperimento AR interessante con Vuforia su Unity, tuttavia abbiamo ancora molte interessanti funzionalità da trattare. Non abbiamo visto nessuna delle risorse Vuforia più sofisticate: Obiettivi, Smart Terrain, Cloud e così via. Resta sintonizzato per le prossime esercitazioni, in cui tratteremo più di queste funzionalità, sempre utilizzando lo stesso approccio passo dopo passo.

A presto!