Lag et Pokémon GO-stilforsterket virkelighetsspill med Vuforia Bildemål

I denne opplæringen drar vi tilbake til biblioteket Vuforia Augmented Reality (AR), og utforsker en av sine mest interessante ressurser - Image Target. Vi utvider på Shoot the Cubes spillet som vi opprettet i tidligere leksjoner, og legger til et nytt nivå hvor spilleren trenger å forsvare sin base fra angripende terninger. 

 

Denne opplæringen kan fullføres alene, men hvis du vil ha en introduksjon til AR med Vuforia og Unity3D, sjekk ut de tidligere innleggene i serien.

Bildemål

Enhver form for bilde kan være et Vuforia Image Target. Men jo mer detaljerte og intrikate bildet, desto bedre blir det gjenkjent av algoritmen. 

Mange faktorer vil være en del av anerkjennelsesberegningen, men i utgangspunktet må bildet ha et rimelig nivå av kontrast, oppløsning og skilleelementer. Et blå himmelfoto ville ikke fungere veldig bra, men et bilde av noe gress ville fungere grasiøst. Bildemål kan sendes med programmet, lastet opp til programmet gjennom skyen, eller direkte opprettet i appen av brukeren.

Legge til et mål

La oss begynne med å legge til en ImageTarget element til vårt Unity-prosjekt. 

Først last ned kursets aktiva fra knappen i sidefeltet. Deretter, i din Unity-prosjekt, opprett en ny scene som heter DefendTheBase: i Prosjekt vindu, velg scener mappe og klikk på Skape > scene. Åpne nå den aktuelle scenen og fjern alle standard sceneobjekter fra hierarkiet.

Neste legger vi til et lys og kamera. Klikk på Legg til > Lys > Retningslys å legge til retningslys. Velg dette nye lyset og sett Myk skygge som Skyggetype alternativ. 

Etter det, dra og slipp en ARCamera objekt fra Vuforia > prefabs. Velg ARCamera objekt og i inspeksjonspanelet, sett inn App lisensnøkkel opprettet på Vuforia-utvikler siden (se første veiledning for instruksjoner). Å velge DEVICE_TRACKING for World Center Mod.

Til slutt dra og slipp en ImageTargettil hierarkiet fra Vuforia > prefabs.

Nå må vi legge til en Vuforia Database. Først naviger til https://developer.vuforia.com/target-manager. Klikk på Legg til database og velg et navn.

Det finnes tre typer database å velge mellom:

  1. Enhet: Databasen er lagret på enheten, og alle målene oppdateres lokalt.
  2. Sky: Database på Vuforia-serverne.
  3. VuMark: Database eksklusiv til VuMark mål. Den lagres også på enheten.

I dette tilfellet velger du Enhet alternativet og klikk på skape.

Velg den nye databasen, slik at vi kan begynne å legge til mål for det. Nå er det på tide å legge til mål i databasen. For nå vil vi bare bruke Enkelt bilde alternativ.

Naviger til de tidligere nedlastede filene, velg ImageTarget1, og sett dens Bredde til 1 og klikk på Legg til. (Merk: Hvis du foretrekker å lage ditt eget bildemål, les veilederen først.)

Nå kan du laste ned databasen, velge Enhetsredaktør som den valgte plattformen. Åpne filen og velg alle elementene som skal importeres. Vi må også forberede vår Unity-scene for å gjenkjenne ImageTarget med denne databasen har vi opprettet.

I Unity-editoren klikker du på JegmageTarget gjenstand. Først, finn og utvide Image Target Behavior i objektinspektøren. Velg en Type av Forhåndsdefinert. Velg bildeformålet vi opprettet tidligere for database. Til slutt, sørg for at Aktiver utvidet sporing og Aktiver smart terreng alternativene er begge deaktivert.

De ImageTarget prefab er laget av en rekke komponenter, inkludert noen skript som Image Target Behavior, Turn Off Behavior, og Standard Tracker Event Handler. Hvis du vil forstå hvordan systemet fungerer, kan du lese disse skriptene og forsøke å forstå deres forhold til andre komponenter. 

For denne opplæringen vil vi ikke grave for dypt, skjønt. Vi trenger bare å konsentrere seg om Standard Tracker Event Handler, som mottar anrop når statusmålingssporingsstatus endres. Så la oss bruke dette skriptet som en base for å lage vår egen skriptadferd.

Lag en kopi av dette skriptet som vi kan utvide. Velg først Standard Tracker Event Handler, klikk på opsjoner og velg Rediger skript. Gjør nå en kopi av skriptet. Hvis du bruker MonoDevelop, klikker du Fil > Lagre som og lagre som ImageTargetBehavior, lagrer det i scripts mappe.

TargetBehaviorScript Script

Vi trenger ikke Vuforia namespace i vårt skript. Fjern linjen "navneområde Vuforia"Og beslagene. Det betyr at vi må eksplisitt referere til Vuforia navneområde når vi ønsker å få tilgang til sine klasser: 

bruker UnityEngine; bruker System.Collections; offentlig klasse BaseScript: MonoBehaviour, Vuforia.ITrackableEventHandler // kode her

Den viktigste metoden i denne klassen vil være OnTrackableStateChanged Metode som mottar samtaler når bildemålet er funnet eller tapt av kameradenheten. Ifølge målstatusen kalles det OnTrackingFound eller OnTrackingLost, og vi må også redigere disse metodene. Men først, la oss tenke på hvordan vi ønsker bildemålet å oppføre seg. 

I dette spillet vil brukeren forsvare en base som vises på et bildemål. La oss vurdere følgende spillmekanikk:

  • Når målet er gjenkjent av systemet, vises basen og fiender begynner å gyte og flyr mot basen i kamikaze-stil.
  • Hver gang en fiende treffer basen, vil basen ta litt skade og fienden blir ødelagt.
  • For å vinne spillet må brukeren skyte og ødelegge alle fiender før basen er ødelagt.
  • Hvis bildemålet er tapt (ikke lenger synlig fra enhetskameraet), starter spillet en nedtellingstidtaker. Hvis timeren kommer til null, går spillet tapt. Mens målet går tapt, stopper alle fiender mot basen.

Så vi må tilpasse disse spillmekanikkene på toppen av det vi bygget i den siste opplæringen. Vi oppretter fiendens gytlogikk i neste del med en tom gjenstand som heter _SpawnController, bruker den samme logikken som ble vedtatt i første del av spillet.

For nå, la oss se på sporing funnet logikken.

privat ugyldig OnTrackingFound () EnableRendererAndCollider (); // Informer systemet om at målet ble funnet StartCoroutine (InformSpawnCtr (true));  privat ugyldig OnTrackingLost () DisableRendererAndCollider (); // Informer systemet om at målet var tapt StartCoroutine (InformSpawnCtr (false));  // informere SpanController at basen ble grunnlagt privat IEnumerator InformSpawnCtr (bool isOn) // flytte gyteposisjon GameObject spawn = GameObject.FindGameObjectWithTag ("_SpawnController"); yield returnerer nye WaitForSeconds (0.2f); // informer SpanController om (isOn) spawn.GetComponent () .BaseOn (transform.position);  ellers spawn.GetComponent () .BaseOff (); 

Tilbake i Unity-redigeringsprogrammet, kan vi opprette basisobjektet som vil bli hentet av gresskontrolleren. 

Først på ImageTarget objekt, deaktivere Standard Trackable Event Handler manus.

Deretter klikker du på Legg til komponent og velg Target Behavior Script. Fra hierarki panel, høyreklikk på ImageTarget og lag en ny kube med navnet "Utgangspunkt". Denne kuben skal settes inn i ImageTarget gjenstand.

Pass på at Utgangspunkt har Box Collider og Mesh Renderer aktivert. 

Eventuelt kan du også sette inn en fly objekt inni ImageTarget bruker ImageTarget sendt tidligere i Vuforia som en tekstur. Dette vil skape en interessant effekt, projisere skygger fra målet og skape en rikere opplevelse.

Tilpasse SpawnScript

Nå skal vi tilpasse _SpawnController brukt i den siste opplæringen. Lagre gjeldende scene og åpne ShootTheCubesMain fra den siste opplæringen. I hierarki panel, velg _SpawnController og dra den til prefabs mappe for å gjøre det til en Enhet Prefab.

Lagre denne nye scenen og gjenåpne DefendTheBase. Dra _SpawnController fra prefabs-mappen til hierarki panel. Med _SpawnController valgt, klikk på Legg til tag på Inspektør panel. Gi den nye taggen navnet _SpawnController og legg det på objektet. 

I prosjektvinduet velger du Cube element i Prefab mappe og angi dens stikkord, tilbake på inspektør, til 'Enemy'.

Til slutt åpner du scripts mappe og åpne SpawnScript. Vi må gjøre dette skriptet tilpasse seg den lastede scenen.

bruker UnityEngine; bruker UnityEngine.SceneManagement; bruker System.Collections; bruker System.Collections.Generic; bruker Vuforia; offentlig klasse SpawnScript: MonoBehaviour #region VARIABLES private bool mSpawningStarted = false; // Cube element å gyte offentlig GameObject mCubeObj; // Qtd av kuber å bli sprukket offentlig int mTotalCubes = 10; private int mCurrentCubes = 0; // Tid til å gyte kubene offentlige flyte mTimeToSpawn = 1f; privat int mDistanceFromBase = 5; privat liste mCubes; privat bool mIsBaseOn; privat scene mScene; #endregion // VARIABLES #region UNITY_METHODS // Bruk dette for initialisering tom Start () mScene = SceneManager.GetActiveScene (); mCubes = ny liste (); hvis (mScene.name == "ShootTheCubesMain") StartSpawn ();  // Oppdatering kalles en gang per ramme ugyldig Oppdatering ()  #endregion // UNITY_METHODS

Deretter må vi opprette to offentlige metoder for å motta samtaler fra TargetBehaviorScript når målet er funnet eller tapt: 

  • BaseOn (Vector3 basePosition) vil bli kalt når målet er funnet av kameraet og Utgangspunkt objekt vises. Det vil endre gyteposisjonen, starte prosessen og informere alle kuber som tidligere ble lagt til scenen som basen er synlig.

  • De BaseOff () Metoden vil bli brukt når målet går tapt. Det vil stoppe prosesseringsprosessen og informere alle kubeelementer om at basen var tapt. 

#region PUBLIC_METHODS // Base ble funnet av Tracker Public Void BaseOn (Vector3 basePosition) Debug.Log ("SpawnScript2: BaseOn"); mIsBaseOn = true; // endre posisjon SetPosition (basePosition); // starte gyteprosessen om nødvendig StartSpawn (); // informere alle kuber på skjermen som basen dukket opp InformBaseOnToCubes ();  // Base tapt av trackerens offentlige tomrom BaseOff () mIsBaseOn = false; mSpawningStarted = false; // informer alle kuber på skjermen som basen er tapt InformBaseOffToCubes ();  #endregion // PUBLIC_METHODS

De SetPosition (System.Nullable pos) bruker målets nåværende posisjon for å endre objektet x, y og z akser, og det kan også motta a null verdi når scenen er lastet ShootTheCubesMain.

#region PRIVATE_METHODS // Vi bruker en Coroutine til å gi litt // forsinkelse før du stiller posisjonen privat IEnumerator ChangePosition () Debug.Log ("ChangePosition"); yield returnerer nye WaitForSeconds (0.2f); // Definer spenningsposisjonen bare en gang // Endre posisjonen bare hvis Vuforia er aktiv hvis (VuforiaBehaviour.Instance.enabled) SetPosition (null);  // Sett posisjonen privat tomt SetPosition (System.Nullable pos) if (mScene.name == "ShootTheCubesMain") // få kameraposisjonen Transform cam = Camera.main.transform; // still inn 10 enheter foran kameraposisjonen transform.position = cam.forward * 10;  annet hvis (mScene.name == "DefendTheBase") if (pos! = null) Vector3 basePosition = (Vector3) pos; transform.position = ny Vector3 (basePosition.x, basePosition.y + mDistanceFromBase, basePosition.z); 

InformBaseOnToCubes () og InformBaseOffToCubes () er ansvarlig for å informere alle iscenesatte kuber av gjeldende basisstatus.

// Informer alle hevede terninger av baseposisjonen private void InformBaseOnToCubes () // Debug.Log ("InformBaseOnToCubes"); foreach (GameObject kube i mCubes) cube.GetComponent () .SwitchBaseStatus (mIsBaseOn);  // Informer alle kubene om at basen er slettet av private informere InformBaseOffToCubes () // Debug.Log ("InformBaseOffToCubes"); foreach (GameObject kube i mCubes) cube.GetComponent () .SwitchBaseStatus (mIsBaseOn); 

De SpawnLoop () og SpawnElement () metoder bruker nesten samme logikk som den siste opplæringen.

// Start gyteprosessen privat tomgang StartSpawn () hvis (! MSpawningStarted) // begynn gyte mSpawningStarted = true; StartCoroutine (SpawnLoop ());  // Loop Spawning kube elementer privat IEnumerator SpawnLoop () if (mScene.name == "ShootTheCubesMain") // Definere gyteposisjonen StartCoroutine (ChangePosition ());  returner tilbake nye WaitForSeconds (0.2f); // Gyting av elementene mens (mCurrentCubes <= (mTotalCubes - 1))  // Start the process with different conditions // depending on the current stage name if (mScene.name == "ShootTheCubesMain" || (mScene.name == "DefendTheBase" && mIsBaseOn))  mCubes.Add (SpawnElement ()); mCubes [mCurrentCubes].GetComponent () .SwitchBaseStatus (mIsBaseOn); mCurrentCubes ++;  Returner nye WaitForSeconds (Random.Range (mTimeToSpawn, mTimeToSpawn * 3));  // Kryd en kube privat GameObject SpawnElement () // kaste elementet i en tilfeldig posisjon, inne i en imaginær sfære GameObject cube = Instantiate (mCubeObj, (Random.insideUnitSphere * 4) + transform.position, transform.rotation) som GameObject; // definere en tilfeldig skala for cube float skalaen = Random.Range (0.5f, 2f); // endre kubeskalaen cube.transform.localScale = ny Vector3 (skala, skala, skala); retur kube;  #endregion // PRIVATE_METHODS

Skaper fiendene

Nå må vi lage noen fiender. Vi bruker Cube objekt som vi opprettet i den siste opplæringen, gjør noen endringer i skriptet.

prefabs mappe, legg til en Cube motsette seg hierarkiet. Velg deretter objektet og rediger CubeBehaviorScript.

Vi beholder nesten samme logikk i dette skriptet, men med følgende forskjeller:

  • De Cube vil forfølge Utgangspunkt når målet er funnet av kameraet.
  • Når Cube treffer Utgangspunkt, det vil ødelegge seg selv og gi litt skade på Utgangspunkt.
  • Skriptet trenger å vite navnet på scenen lastet og tilpasse seg tilsvarende. 
bruker UnityEngine; bruker UnityEngine.SceneManagement; bruker System.Collections; offentlig klasse CubeBehaviorScript: MonoBehaviour #region VARIABLES public float mScaleMax = 1f; offentlig float mScaleMin = 0.2f; offentlig int mCubeHealth = 100; // Orbit max Speed ​​offentlig float mOrbitMaxSpeed ​​= 30f; offentlig flythastighetToBase = 0,4f; offentlig int skade = 10; // Orbit hastighet privat float mOrbitSpeed; // Orbit retning privat Vector3 mOrbitDirection; // Max Cube Scale Private Vector3 mCubeMaxScale; // Growing Speed ​​offentlig float mGrowingSpeed ​​= 10f; privat bool mIsCubeScaled = false; privat bool mIsAlive = true; privat AudioSource mExplosionFx; privat GameObject mBase; privat bool mIsBaseVisible = false; privat Vector3 mRotationDirection; privat scene mScene; #endregion

Hvis sceneens navn er DefendTheBase, det må finne Utgangspunkt objekt og begynn å bevege seg mot det.

#region UNITY_METHODS void Start () // Få scene navn mScene = SceneManager.GetActiveScene (); CubeSettings ();  ugyldig oppdatering () // gjør kubens bane og roterer RotateCube (); hvis (mScene.name == "DefendTheBase") // flytte terningen mot basen, når den er synlig MoveToBase ();  // skala kube om nødvendig hvis (! mIsCubeScaled) ScaleObj ();  #endregion

De CubeSettings () må også tilpasses i henhold til scenen lastet. De Cube bare baner på y-aksen for DefendTheBase scene.

#region PRIVATE_METHODS private void CubeSettings () // definerer bane-retningen float x = Random.Range (-1f, 1f); float y = Random.Range (-1f, 1f); float z = Random.Range (-1f, 1f); // TODO oppdater opplæring med ny kode // definere innstillinger etter scene navn hvis (mScene.name == "ShootTheCubesMain") mOrbitDirection = ny Vector3 (x, y, z);  ellers hvis (mScene.name == "DefendTheBase") // bane bare på y-aksen mOrbitDirection = ny Vector3 (0, y, 0); // skala størrelsen må begrenses mScaleMin = 0.05f; mScaleMax = 0.2f; hastighetToBase = 0,2f;  // roterer rundt sin akse float rx = Random.Range (-1f, 1f); float ry = Random.Range (-1f, 1f); float rz = Random.Range (-1f, 1f); mRotationDirection = ny Vector3 (rx, ry, rz); // definerer hastighet mOrbitSpeed ​​= Tilfeldig.Range (5f, mOrbitMaxSpeed); // definerer skala flyte skala = Tilfeldig.Range (mScaleMin, mScaleMax); mCubeMaxScale = ny Vector3 (skala, skala, skala); // sett kubeskala til 0, for å vokse den senere transform.localScale = Vector3.zero; // få eksplosjon lydeffekt mExplosionFx = GetComponent (); 

Vi legger til litt ny logikk på RotateCube () metode. Kubeobjektene roterer rundt basen mens målet er synlig. Når målet ikke er synlig, fortsetter de å rotere rundt Kamera, bruker samme logikk som i den siste opplæringen.

// Roter kuben rundt basen privatrommet RotateCube () // roter rundt basen eller kameraet hvis (mIsBaseVisible && mBase! = Null && mIsAlive) // roter terning rundt base transform.RotateAround (mBase.transform.position, mOrbitDirection , mOrbitSpeed ​​* Time.deltaTime);  ellers transform.RotateAround (Camera.main.transform.position, mOrbitDirection, mOrbitSpeed ​​* Time.deltaTime);  transform.Rotate (mRotationDirection * 100 * Time.deltaTime);  // Skalobjekt fra 0 til 1 privat tomrom ScaleObj () // voksende obj hvis (transform.localScale! = MCubeMaxScale) transform.localScale = Vector3.Lerp (transform.localScale, mCubeMaxScale, Time.deltaTime * mGrowingSpeed); ellers mIsCubeScaled = true; 

For å flytte objektet mot basen, må vi først sjekke om basen er til stede, og bruk deretter trinnene til objektet.

 // Flytt kuben mot basen privat void MoveToBase () // gjør kuben flytte mot basen bare hvis basen er til stede hvis (mIsBaseVisible && mIsAlive && gameObject! = Null && mBase! = Null) float step = velocityToBase * Time.deltaTime; transform.position = Vector3.MoveTowards (transform.position, mBase.transform.position, trinn); 

De DestroyCube () Metoden er den samme som før, men nå legger vi til en ny metode-the TargetHit (GameObject) metode-som vil bli kalt når basen er rammet. Legg merke til at BaseHealthScript referert i TargetHit () har ikke blitt opprettet ennå.

// skade på mål privat tomt TargetHit (GameObject mål) Debug.Log ("TargetHit:" + target.name); hvis (target.name == "Base") // skade på base MyBase baseCtr = target.GetComponent (); baseCtr.TakeHit (skade); StartCoroutine (DestroyCube ());  // Destroy Cube Private IEnumerator DestroyCube () mIsAlive = false; mExplosionFx.Play (); GetComponent() .enabled = false; yield returnerer nye WaitForSeconds (mExplosionFx.clip.length); Ødelegge (gameObject);  #endregion

Til slutt legger vi til de offentlige metodene som skal ringes når kuben tar en hit, når den kolliderer med basen, eller når basen endrer status.

#region PUBLIC_METHODS // Cube gor Hit // return "false" når kuben ble ødelagt offentlig bool Hit (int hitDamage) mCubeHealth - = hitDamage; hvis (mCubeHealth> = 0 && mIsAlive) StartCoroutine (DestroyCube ()); returnere sant;  returner falsk;  Offentlig ugyldig OnCollisionEnter (Collision Col) TargetHit (col.gameObject);  // Motta nåværende base status offentlig tomgang SwitchBaseStatus (bool isOn) // stopp kuben på bevegelsen mot base mIsBaseVisible = isOn; hvis (isOn) mBase = GameObject.Find ("Base");  ellers mBase = null;  #endregion

Kontrollerer bashelsen

Fiender blir iscenesatt og flyr mot basen, men de gir ingen skade når de kolliderer - hverken til basen eller til fienden. Vi må lage et skript for å svare på kollisjoner og også legge til en helsestang på skjermen, slik at brukeren vet hvor godt de gjør.

La oss begynne å legge til helsestangen. I hierarki panelet i Unity-editoren, klikk på Skape > UI > Slider. En ny Lerret element vil bli lagt til hierarkiet. Den inneholder UI-elementer, inkludert den nye Slider. Utvid Lerret og velg Slider.

Endre gliderenhetens navn til UIHealth. I Inspektør panel, utvide Rect Transform og sett Bredde til 400 og Høyde til 40. Sett Pos X til -220Pos Y til 30, og Pos Z til 0.

Utvid nå skyvekontrollen i hierarkiet. Fjern markeringen av Interactable alternativ. Til Target Graphic, klikk på den lille "prikken" på høyre side og velg Bakgrunn bilde. 

  • Sett Min verdi til 0 og Maks verdi til 100.
  • Å velge Hele tall.
  • Sett Verdi til 100.

Nå, utvide Slider panel for å avsløre barnets elementer: Bakgrunn, Fyllområde, og Håndtak Slide Area.

  • Slett Håndtak Slide Area.
  • Å velge Bakgrunn og sett dens Farge til en mørkere nyanse av grønn, som # 12F568FF.
  • Utvide Fyllområde og velg Fylle objekt og sett fargen til # 7FEA89FF.

Dette er hvordan Spillvindu bør se på helsestangen.

The Base Health Script

Koden er veldig enkel; det trekker bare skaden fra fiender fra den totale mengden av basenes helse. Når helsen kommer til null, taper spilleren spillet. Det vil også legge til en rotasjonsanimasjon til basen. Opprett et nytt C # -skript som heter MyBase.

bruker UnityEngine; bruker UnityEngine.UI; bruker System.Collections; offentlig klasse MyBase: MonoBehaviour #region VARIABLE offentlig float rotationSpeed ​​= 10f; offentlig int helse = 100; offentlig AudioClip explosionSoundFx; offentlig AudioClip hitSoundFx; // TODO velg en annen lyd for Hit private bool mIsAlive = true; privat AudioSource mAudioSource; offentlig Slider mHealthSlider; #endregion // VARIABLES #region UNITY_METHODS // Bruk dette for initialisering tomt Start () mAudioSource = GetComponent (); mHealthSlider.maxValue = helse; mHealthSlider.value = helse;  // Oppdatering kalles en gang per ramme ugyldig Oppdatering () RotateBase ();  #endregion // UNITY_REGION #region PRIVATE_METHODS private void RotateBase () if (mIsAlive && gameObject! = null) // implementere rotasjonsomforming for objekt.Rotere (Vector3.up, rotasjonshastighet * Time.deltaTime);  // Destroy base private IEnumerator DestroyBase () mIsAlive = false; mAudioSource.clip = explosionSoundFx; mAudioSource.Play (); GetComponent () .enabled = false; // informer alle fiendene som Base er Lost GameObject [] enemies = GameObject.FindGameObjectsWithTag ("Fiend"); foreach (GameObject e i fiender) exampleameObject.GetComponent () .SwitchBaseStatus (false);  returner tilbake nye WaitForSeconds (mAudioSource.clip.length); Destroy (gameObject);  #endregion // PRIVATE_METHODS #region PUBLIC_METHODS // mottar skade offentlig tomgang TakeHit (int skade) helse - = skade; mHealthSlider.value = helse; hvis (helse <= 0)  StartCoroutine (DestroyBase ());  else  mAudioSource.clip = hitSoundFx; mAudioSource.Play ();   #endregion // PUBLIC_METHODS 

Nå må vi legge til og konfigurere skriptet. 

Velg Utgangspunkt i hierarkiet, klikk på Legg til komponent, og legg til en Lydkilde. Dra nå MyBase til Utgangspunkt element og, i Inspektør panel, utvide MyBase. Velg en lydeffekt for eksplosjonen og trykk. Jeg har brukt eksplosjon klipp brukt i den siste opplæringen, men vær så snill å legge til din egen. Til slutt, i Health Slider, velg UISlider element.

Forsvare basen

Vår nye spillopplevelse er nesten ferdig. Vi trenger bare å skyte noen lasere for å forsvare vår base. La oss lage et skript for laseren! 

Først dra _PlayerController fra Prefab mappe til hierarkiet. Utvide _PlayerController og velg _LaserController. i Inspektør panel, finn Laser Script og klikk på Redigere.

Det eneste vi må bytte i dette skriptet er laserposisjonen.

// Skru Laser privat tomrumsbrann () // Få ARCamera Transform Transform cam = Camera.main.transform; // Definer tidspunktet for neste brann mNextFire = Time.time + mFireRate; // Angi opprinnelsen til RayCast Vector3 rayOrigin = cam.position; // Vis laseren ved hjelp av en Coroutine StartCoroutine (LaserFx ()); // Holder hit informasjonen RaycastHit hit; // Sett opprinnelsesposisjonen til laserlinjen // Det vil legge til 10 enheter ned fra ARCamera // Vi vedtok denne logikken for enkelhet Vector3 laserStartPos = ny Vector3 (cam.position.x, cam.position.y -2f, cam .position.z); mLaserLine.SetPosition (0, laserStartPos); // Sjekk om RayCast treffer noe hvis (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Still inn enden av laserlinjen til objektet hit mLaserLine.SetPosition (1, hit.point) ; // sjekk måltype hvis (hit.collider.tag == "Enemy") CubeBehaviorScript cubeCtr = hit.collider.GetComponent (); hvis (cubeCtr! = null) if (hit.rigidbody! = null) hit.rigidbody.AddForce (-hit.normal * mHitForce); cubeCtr.Hit (mLaserDamage);  ellers // Still inn enfo på laserlinjen for å videresende kameraet // ved hjelp av laserområdet mLaserLine.SetPosition (1, cam.forward * mFireRange); 

Prøver ut spillet

 

Det var mye arbeid, men nå er det på tide å spille spillet! Skriv ut målbildet og prøv å kjøre spillet på telefonen eller nettbrettet. Ha det gøy med det og se om du kan komme opp på noen måter å forbedre spillet! 

På dette tidspunktet har du en god forståelse av hvordan Vuforia-systemet fungerer og hvordan du bruker det med Unity. Jeg forventer at du har hatt denne reisen så mye som jeg har. Ser deg snart!

For å lære mer om Augmented Reality med Vuforia og Unity, sjekk ut vårt videokurs her på Envato Tuts+!