În ultimul post al acestei serii, am învățat cum să instalăm Vuforia și să începem să dezvoltăm un joc AR de la zero, adoptând o logică similară cu cea folosită pe Pokémon GO!
Am început dezvoltarea unui joc Realitatea Augmented numit Shoot the Cubes. Acum este momentul să îmbunătățiți jocul prin adăugarea interacțiunii și făcând experiența mai angajată. Ne vom concentra mai mult pe posibilitățile pe care le oferă Unitatea, lăsând deoparte specificul lui Vuforia. Experiența cu motorul Unity nu este obligatorie.
Să începem să lucrăm la jocul nostru. Până acum, am reușit să creăm o scenă de realitate augmentată care se mișcă cu dispozitivul utilizatorului. Vom îmbunătăți această aplicație, făcând cuburile să se arunce în aer și să zboare în jur și lăsându-l pe jucătorul să-l caute și să-l distrugă cu o fotografie laser.
Am stabilit deja o poziție inițială a _SpawnController în funcție de rotația aparatului foto. Acum vom stabili o zonă în jurul valorii de acest punct în care se vor produce cuburile noastre. Acum vom actualiza SpawnScript
pentru a face _SpawnController instanțiate elementele de cub cu diferite mărimi și poziții aleatoare, față de _SpawnController.
Să editați SpawnScript
clasă, adăugând câteva variabile pentru a controla procesul de reproducere.
clasa publica SpawnScript: MonoBehavior // Elementul Cub pentru publicarea GameObject mCubeObj; // Qtd de cuburi care urmează să fie răspândite public int mTotalCubes = 10; // Timpul pentru a da naștere cuburilor public float mTimeToSpawn = 1f; // țineți toate cuburile pe scenă privat GameObject [] mCubes; // definiți dacă poziția a fost setată privat bool mPositionSet;
Vom crea o corutină numită SpawnLoop
pentru a gestiona procesul de spawn. De asemenea, va fi responsabil de stabilirea poziției inițiale a _SpawnController când începe jocul. Observați că Random.insideUnitSphere
metoda determină cuburile să fie instanțiate în locații aleatorii într-o zonă sferică din jurul _SpawnManager.
clasa publica SpawnScript: MonoBehavior // Buclă Cresterea elementelor cub private IEnumerator SpawnLoop () // Definirea poziției de nădejde StartCoroutine (ChangePosition ()); randamentul randament nou WaitForSeconds (0.2f); // Înmulțirea elementelor int i = 0; in timp ce eu <= (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;
În cele din urmă, editați Start()
funcţie. Asigurați-vă că ați scos-o StartCoroutine (ChangePosition ());
și înlocuiți-l cu un apel pentru a porni SpawnLoop
coroutine.
clasa publică SpawnScript: MonoBehavior void Start () // Inițierea buclă de reproducere StartCoroutine (SpawnLoop ()); // Inițializați matricea de cuburi în funcție de // cantitatea dorită mCubes = new GameObject [mTotalCubes];
Acum, înapoi în unitate, va trebui să creați un prefab cub care să fie instanțiat de scenariu.
SpawnScript
zona inspectorului.Acum, dacă apăsați butonul de redare în Unitate și executați proiectul pe dispozitiv, ar trebui să vedeți cuburile care reproduc.
Trebuie să adăugăm mișcare acestor cuburi pentru a face lucrurile mai interesante. Să rotim cuburile în jurul axelor lor și peste ARCamera. De asemenea, ar fi bine să adăugați un factor aleator asupra mișcării cubului pentru a crea o simțire mai organică.
Trageți cub Prefabricați din prefabricate dosarului la ierarhie.
Fiecare cub va avea caracteristici aleatorii. Mărimea, viteza de rotație și direcția de rotație vor fi definite aleatoriu, utilizând câteva referințe definite anterior. Să creăm unele variabile ale controlerului și să inițializăm starea cubului.
utilizând UnityEngine; utilizând System.Collections; clasa publică CubeBehaviorScript: MonoBehavior // Cube's Max / Min scară public float mScaleMax = 2f; float public mScaleMin = 0.5f; // Orbit max Viteză publică flotantă mOrbitMaxSpeed = 30f; // viteza orbită privată float mOrbitSpeed; // Punct de ancorare pentru ca Cubul să se rotească în jurul privatului Transformare mOrbitAnchor; // direcția orbită privată Vector3 mOrbitDirection; // Max Cube Scale privat Vector3 mCubeMaxScale; // Mărirea vitezei publice float mGrowingSpeed = 10f; bool privat mIsCubeScaled = false; void Start () CubeSettings (); // Setați setările cubului inițial void privat CubeSettings () // definirea punctului de ancorare drept camera principală mOrbitAnchor = Camera.main.transform; // definirea direcției orbite float x = Random.Range (-1f, 1f); float y = Random.Range (-1f, 1f); float z = Random.Range (-1f, 1f); mOrbitDirection = Vector3 nou (x, y, z); // definirea vitezei mOrbitSpeed = Random.Range (5f, mOrbitMaxSpeed); // definește scale scară float = Random.Range (mScaleMin, mScaleMax); mCubeMaxScale = Vector3 nou (scară, scală, scală); // set cub scară la 0, pentru a crește it lates transform.localScale = Vector3.zero;
Acum este momentul să adăugați o mișcare în cubul nostru. Să facem să se rotească în jurul ei și în jurul valorii de ARCamera, utilizând viteza și direcția aleatorii definite mai devreme.
// Actualizarea se numește o singură dată pentru fiecare cadru. Update () // face orbita cubului și rotește RotateCube (); // face cubul să se rotească în jurul unui punct de ancorare // și să se rotească în jurul axei sale private void RotateCube () // rotiți cubul în jurul camerei transform.RotateAround (mOrbitAnchor.position, mOrbitDirection, mOrbitSpeed * Time.deltaTime); // se rotește în jurul axei sale transforma.Rotați (mOrbitDirection * 30 * Time.deltaTime);
Pentru a deveni mai organic, cubul va crește până la mărimea zero după ce va fi dat naștere.
// Actualizarea se numește o singură dată pentru fiecare cadru. Update () // face orbita cubului și rotește RotateCube (); // scară cub dacă este necesar dacă (! mIsCubeScaled) ScaleObj (); // Scalare obiect de la 0 la 1 void privat ScaleObj () // cresterea vol if (transform.localScale! = MCubeMaxScale) transform.localScale = Vector3.Lerp (transform.localScale, mCubeMaxScale, Time.deltaTime * mGrowingSpeed); altfel mIsCubeScaled = true;
Cuburile astea sunt prea fericite care zboară în jur. Trebuie să le distrugem cu lasere! Să creăm un pistol în jocul nostru și să începem să-i împușcăm.
Fotografia laser trebuie conectată la ARCamera și rotația sa. De fiecare dată când playerul "prăbușește" ecranul dispozitivului, va fi împușcat un laser. Vom folosi Physics.Raycast
clasa pentru a verifica dacă laserul a lovit țintă și, dacă este așa, vom elimina unele de sănătate de la ea.
Interior LaserScript, vom folosi a LineRenderer
pentru a afișa raza laser, folosind un punct de origine conectat la partea inferioară a ecranului ARCamera. Pentru a obține punctul de origine al razei laser - cilindrul pistolului virtual - vom obține camera Transforma
în momentul în care un laser este împușcat și mutați-l cu 10 unități în jos.
Mai întâi, să creăm câteva variabile pentru a controla setările laserului și pentru a obține mLaserLine
.
utilizând UnityEngine; utilizând System.Collections; public class LaserScript: MonoBehour public float mFireRate = .5f; float public mFireRange = 50f; float public mHitForce = 100f; public int mlaserDamage = 100; / / Realizează linia care va reprezenta linia laser privată LineRenderer mLaserLine; // Definirea dacă linia laser este afișată privat bool mLaserLineEnabled; // Timpul în care liniile laser afișează pe ecran privat WaitForSeconds mLaserDuration = new WaitForSeconds (0.05f); // timpul de până la următoarea incendiu privat float mNextFire; // Folosiți acest lucru pentru inițierea void Start () // obținerea Line Renderer mLaserLine = GetComponent();
Funcția responsabilă de fotografiere este Foc()
. Aceasta va fi chemată de fiecare dată când jucătorul apasă butonul de foc. Observa asta Camera.main.transform
este folosit pentru a obține ARCamera poziția și rotația și că laserul este poziționat la 10 unități deasupra acestuia. Aceasta poziționează laserul din partea inferioară a camerei.
// Shot laser privat void Fire () // Obțineți ARCamera Transform Transform cam = Camera.main.transform; // Definirea timpului următorului incendiu mNextFire = Time.time + mFireRate; // Setați originea RayCast Vector3 rayOrigin = locație; // Setați poziția de origine a liniei laser // Va fi întotdeauna 10 unități în jos de la ARCamera // Am adoptat această logică pentru simplitatea mLaserLine.SetPosition (0, transform.up * -10f);
Pentru a verifica dacă țintă a fost lovită, vom folosi a Raycast
.
// Shot Laser privat void Fire () // Țineți Hit informații RaycastHit lovit; // Verifică dacă RayCast a lovit ceva dacă (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Setați sfârșitul liniei laser la obiectul loves mLaserLine.SetPosition (1, hit.point) ; altfel // Setați enfo-ul liniei laser pentru a avansa camera // folosind gama laserului mLaserLine.SetPosition (1, cam.forward * mFireRange);
În cele din urmă, este timpul să verificați dacă butonul de foc a fost apăsat și să apelați efectele laser atunci când focul este declanșat.
// Actualizarea se numește o singură dată pentru fiecare cadru. () If (Input.GetButton ("Fire1") && Time.time> mNextFire) Fire (); privat void Fire () // codul anterior suprimat pentru simplitate // Afișați laserul folosind un Coroutine StartCoroutine (LaserFx ()); // Afișează Laser Efecte private IEnumerator LaserFx () mLaserLine.enabled = true; // Cale pentru o anumită perioadă de timp pentru a elimina randamentul randamentului LineRenderer mLaserDuration; mLaserLine.enabled = false;
Înapoi în Unitate va trebui să adăugăm o LineRenderer
componenta la _LaserController obiect.
Dacă încercați jocul acum, ar trebui să vedeți un laser care este împușcat din partea de jos a ecranului. Simțiți-vă liber să adăugați un Sursă audio componentă cu un efect de sunet laser la _LaserController pentru a-l condim.
Lăzile noastre trebuie să-și atingă țintele, să le facă daune și, eventual, să distrugă cuburile. Va trebui să adăugăm o Corp rigid la cuburi, aplicarea forței și deteriorarea lor.
Acum, să editați CubeBehavior
script pentru a crea o functie responsabila de aplicarea daunelor asupra cubului si o alta pentru ao distruga atunci cand starea de sanatate scade sub 0.
clasa publică CubeBehaviorScript: MonoBehavior // Cube Health public int mCubeHealth = 100; // Definiți dacă cubul este în viață privit bool mIsAlive = true; // Cube a fost lovit // return 'false' cand cubul a fost distrus public bool Hit (int hitDamage) mCubeHealth - = hitDamage; dacă (mCubeHealth> = 0 && mIsAlive) StartCoroutine (DestroyCube ()); return true; return false; // Destroy Cube privat IEnumerator DestroyCube () mIsAlive = false; // Faceți cubul desappear GetComponent() .enabled = false; // vom aștepta ceva timp înainte de a distruge elementul // aceasta este utilă atunci când folosiți un fel de efect // ca un efect de sunet de explozie. // în acest caz am putea folosi lungimea sunetului ca timp de așteptare a randamentului retur nou WaitForSeconds (0.5f); Distruge (gameObject);
Bine, cubul se poate distruge acum și poate fi distrus. Să editați LaserScript
pentru a aplica daune cubului. Tot ce trebuie să facem este să schimbăm Foc()
funcția de a apela Lovit
metodă a CubeBehavior
scenariu.
public class LaserScript: MonoBehavior // Shot Laser privat void Fire () // cod suprimat pentru simplitate ... // Verifică dacă RayCast a lovit ceva dacă (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Setați sfârșitul liniei laser la obiectul loved mLaserLine.SetPosition (1, hit.point); // Obțineți scriptul CubeBehavior pentru a aplica daunele la adresa CubeBehaviorScript cubeCtr = hit.collider.GetComponent(); dacă (cubeCtr! = null) if (hit.rigidbody! = null) // aplicați forța țintă hit.rigidbody.AddForce (-hit.normal * mHitForce); // aplicați deteriorarea target cubeCtr.Hit (mLaserDamage);
Felicitări! Jocul nostru Realitatea Augmented este terminat! Da, jocul ar putea fi mai lustruit, dar elementele de bază sunt acolo și experiența generală este destul de interesantă. Pentru a-l face mai interesant, ai putea adăuga o explozie de particule, așa cum am făcut-o în videoclip, și în plus, ai putea adăuga un sistem de scor sau chiar un sistem de undă cu un temporizator pentru a face mai mult o provocare. Pașii următori sunt pe contul dvs.!
Am creat un experiment AR interesant, folosind Vuforia pe unitate, dar totuși avem multe caracteristici interesante pentru a le acoperi. Nu am văzut niciuna dintre resursele mai sofisticate ale Vuforia: Ținte, Smart Terrain, Cloud și așa mai departe. Rămâi acordat pentru următoarele tutoriale, unde vom acoperi mai multe dintre aceste caracteristici, folosind întotdeauna aceeași abordare pas cu pas.
Ne vedem în curând!