I det siste innlegget i denne serien lærte vi å sette opp Vuforia og begynne å utvikle et AR-spill fra bunnen av, ved å vedta en logikk som ligner den som ble brukt på Pokémon GO!
Vi har begynt å utvikle et Augmented Reality-spill som heter Shoot the Cubes. Nå er det på tide å forbedre spillet ved å legge til interaksjon og gjøre opplevelsen mer engasjerende. Vi vil mest konsentrere oss om mulighetene Unity gir oss, etterlater Vuforias spesifikasjoner. Erfaring med Unity-motoren er ikke obligatorisk.
La oss begynne å jobbe med spillet vårt. Så langt har vi klart å lage en Augmented Reality-scene som beveger seg med brukerens enhet. Vi forbedrer denne appen ved å gjøre kubene gyte og fly rundt, og ved å la spilleren søke og ødelegge dem med et laserskudd.
Vi har allerede satt en startposisjon for _SpawnController i henhold til enhetskameraets rotasjon. Nå etablerer vi et område rundt dette punktet hvor våre kuber vil gyte. Nå oppdaterer vi SpawnScript
å gjøre _SpawnController Installer kubeelementene med forskjellige størrelser og tilfeldige posisjoner, i forhold til _SpawnController.
La oss redigere SpawnScript
klasse, og legger til noen variabler for å kontrollere gyteprosessen.
offentlig klasse SpawnScript: MonoBehaviour // Cube element for å gyte offentlig GameObject mCubeObj; // Qtd av kuber å bli sprukket offentlig int mTotalCubes = 10; // Tid til å gyte kubene offentlige flyte mTimeToSpawn = 1f; // hold alle kuber på scenen privat GameObject [] mCubes; // definere om posisjonen ble satt privat bool mPositionSet;
Vi lager en koroutin som heter SpawnLoop
å administrere gyteprosessen. Det vil også være ansvarlig å sette startposisjonen til _SpawnController når spillet begynner. Legg merke til at Random.insideUnitSphere
Metoden fører til at kubene blir instantiated på tilfeldige steder innenfor et sfærisk område rundt _SpawnManager.
offentlig klasse SpawnScript: MonoBehaviour // Loop Spawning-kubeelementer privat IEnumerator SpawnLoop () // Definere gyteposisjonen StartCoroutine (ChangePosition ()); yield returnerer nye WaitForSeconds (0.2f); // Gyting av elementene int i = 0; mens jeg <= (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;
Endelig rediger du Start()
funksjon. Pass på at du fjerner StartCoroutine (ChangePosition ());
linje og erstatt det med et anrop for å starte SpawnLoop
coroutine.
offentlig klasse SpawnScript: MonoBehaviour void Start () // Initialisering av gybsløyfe StartCoroutine (SpawnLoop ()); // Initialiser Cubes array i henhold til // ønsket mengde mCubes = new GameObject [mTotalCubes];
Nå tilbake i Unity må du lage en kube prefab for å bli instantiated av skriptet.
SpawnScript
inspektørens område.Nå, hvis du trykker på spill i Unity og kjører prosjektet på enheten, bør du se kubene gyte.
Vi må legge til bevegelse til de kuber for å gjøre ting mer interessant. La oss rotere terningene rundt sine akser og over ARCamera. Det ville også være kult å legge til noen tilfeldig faktor over terningbevegelsen for å skape en mer organisk følelse.
Dra Cube Prefab fra prefabs mappe til hierarkiet.
Hver kube vil ha tilfeldige egenskaper. Størrelsen, rotasjonshastigheten og rotasjonsretningen vil bli definert tilfeldig, ved hjelp av noen referanser som tidligere er definert. La oss lage noen kontrollervariabler og initialisere tilstanden til kuben.
bruker UnityEngine; bruker System.Collections; offentlig klasse CubeBehaviorScript: MonoBehaviour // Cube er Max / Min skala offentlig float mScaleMax = 2f; offentlig float mScaleMin = 0.5f; // Orbit max Speed offentlig float mOrbitMaxSpeed = 30f; // Orbit hastighet privat float mOrbitSpeed; // Ankerpunkt for kuben å rotere rundt privat Transform mOrbitAnchor; // Orbit retning privat Vector3 mOrbitDirection; // Max Cube Scale Private Vector3 mCubeMaxScale; // Growing Speed offentlig float mGrowingSpeed = 10f; privat bool mIsCubeScaled = false; void Start () CubeSettings (); // Angi innledende kubeinnstillinger private void CubeSettings () // definere ankerpunktet som hovedkameraet mOrbitAnchor = Camera.main.transform; // definere bane retningen float x = Random.Range (-1f, 1f); float y = Random.Range (-1f, 1f); float z = Random.Range (-1f, 1f); mOrbitDirection = ny Vector3 (x, y, z); // 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 det lates transform.localScale = Vector3.zero;
Nå er det på tide å legge litt bevegelse til kuben vår. La oss få det til å rotere rundt seg selv og rundt ARCamera, ved hjelp av tilfeldig hastighet og retning definert tidligere.
// Oppdatering kalles en gang per ramme ugyldig Oppdatering () // gjør kubens bane og roterer RotateCube (); // Gjør kuben roter rundt et ankerpunkt // og roter rundt sin egen akse. Privat void RotateCube () // roter terningen rundt kameraet transformer.RotateAround (mOrbitAnchor.position, mOrbitDirection, mOrbitSpeed * Time.deltaTime); // rotere rundt sin akse transform.Rotere (mOrbitDirection * 30 * Time.deltaTime);
For å gjøre det mer organisk, vil kuben skalere opp fra størrelse null etter at den er oppstått.
// Oppdatering kalles en gang per ramme ugyldig Oppdatering () // gjør kubens bane og roterer RotateCube (); // skala kube hvis nødvendig hvis (! mIsCubeScaled) ScaleObj (); // 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;
De kuberne er for glade flyr rundt slik. Vi må ødelegge dem med lasere! La oss lage en pistol i vårt spill og begynne å skyte dem.
Laserskuddet må være koblet til ARCamera og dens rotasjon. Hver gang spilleren "tapper" enhetens skjerm, blir en laser skutt. Vi bruker Physics.Raycast
klassen for å sjekke om laseren slår målet og i så fall vil vi fjerne litt helse fra den.
Innsiden LaserScript, vi bruker en LineRenderer
for å vise laserstrålen, ved hjelp av et opprinnelsespunkt som er koblet til bunnen av ARCamera. For å få opprinnelsespunktet til laserstrålen - den virtuelle pistolens fat - vi får kameraet Forvandle
i det øyeblikket en laser er skutt og flytte den 10 enheter ned.
La oss først lage noen variabler for å kontrollere laserinnstillingene og få mLaserLine
.
bruker UnityEngine; bruker System.Collections; offentlig klasse LaserScript: MonoBehaviour public float mFireRate = .5f; offentlig float mFireRange = 50f; offentlig float mHitForce = 100f; offentlig int mLaserDamage = 100; // Linje gjengivelse som representerer Laser Private LineRenderer mLaserLine; // Definer om laserlinjen viser privat bool mLaserLineEnabled; // Tid som laser linjene viser på skjermen privat WaitForSeconds mLaserDuration = nye WaitForSeconds (0.05f); // tid til neste brann, private flyte mNextFire; // Bruk dette for initialisering tomt Start () // får linjeleverandøren mLaserLine = GetComponent();
Funksjonen som er ansvarlig for fotografering er Brann()
. Det vil bli kalt hver gang spilleren trykker på brannknappen. Legg merke til det Camera.main.transform
blir brukt til å få ARCamera posisjon og rotasjon og at laseren er plassert 10 enheter under det. Dette posisjonerer laseren nederst på kameraet.
// 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; // Sett opprinnelsesposisjonen til laserlinjen // Den vil alltid 10 enheter ned fra ARCamera // Vi vedtok denne logikken for enkelhet mLaserLine.SetPosition (0, transform.up * -10f);
For å sjekke om målet ble truffet, bruker vi en Raycast
.
// Skru Laser privat tomrom Brann () // Hold Hit-informasjonen RaycastHit hit; // 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) ; ellers // Still inn enfo for laserlinjen for å vende kameraet // ved hjelp av laserområdet mLaserLine.SetPosition (1, cam.forward * mFireRange);
Til slutt er det på tide å sjekke om brannknappen ble trykket og ringe til laservirkningen når skottet blir sparket.
// Oppdatering kalles en gang per ramme ugyldig Oppdatering () hvis (Input.GetButton ("Fire1") && Time.time> mNextFire) Fire (); privat ugyldig brann () // fremre kode undertrykt for enkelhet // Vis laseren ved hjelp av en Coroutine StartCoroutine (LaserFx ()); // Vis lasereffekter private IEnumerator LaserFx () mLaserLine.enabled = true; // Vei for en bestemt tid for å fjerne LineRenderer avkastningsavkastning mLaserDuration; mLaserLine.enabled = false;
Tilbake i Unity må vi legge til en LineRenderer
komponent til _LaserController gjenstand.
Hvis du tester spillet nå, bør du se en laser bli skutt fra bunnen av skjermen. Du er velkommen til å legge til en AudioSource komponent med laserlyd effekt til _LaserController å krydre det opp.
Våre lasere må slå sine mål, bruke skade og til slutt ødelegge kubene. Vi må legge til en Stiv kropp til terningene, påføring av kraft og skade på dem.
La oss nå redigere CubeBehavior
skript for å skape en funksjon som er ansvarlig for å påføre skade på kuben og en annen for å ødelegge den når helsen faller under 0.
offentlig klasse CubeBehaviorScript: MonoBehaviour // Cube Health public int mCubeHealth = 100; // Definer om kuben er i live privat bool mIsAlive = true; // Cube fikk 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; / / Destroy Cube Private IEnumerator DestroyCube () mIsAlive = false; // Gjør kuben forsvinner GetComponent() .enabled = false; // vi venter litt tid før du ødelegger elementet // dette er nyttig når du bruker en slags effekt // som en eksplosjonslyd effekt. // i så fall kan vi bruke lydlengden som ventetidavkastning, returnere nye WaitForSeconds (0.5f); Ødelegge (gameObject);
Ok, kuben kan nå skade og bli ødelagt. La oss redigere LaserScript
å påføre skade på terningen. Alt vi trenger å gjøre er å endre Brann()
funksjon å ringe Truffet
metode av CubeBehavior
manus.
offentlig klasse LaserScript: MonoBehaviour // Skjer Laser Private Void Fire () // kode undertrykt for enkelhet ... // Kontrollerer om RayCast treffer noe hvis (Physics.Raycast (rayOrigin, cam.forward, out hit, mFireRange)) // Sett slutt på laserlinjen til objektet hentet mLaserLine.SetPosition (1, hit.point); // Få CubeBehavior-skriptet til å bruke skade på målet CubeBehaviorScript cubeCtr = hit.collider.GetComponent(); hvis (cubeCtr! = null) if (hit.rigidbody! = null) // gjelder kraft til målet hit.rigidbody.AddForce (-hit.normal * mHitForce); // bruk skade målet cubeCtr.Hit (mLaserDamage);
Gratulerer! Vårt Augmented Reality-spill er ferdig! Ja, spillet kan være mer polert, men det grunnleggende er det, og den generelle opplevelsen er ganske engasjerende. For å gjøre det mer interessant kan du legge til en partikkeleksplosjon, som jeg gjorde i videoen, og i tillegg kan du legge til et poengsum eller et bølgesystem med en timer for å gjøre det mer utfordrende. De neste trinnene er opp til deg!
Vi opprettet et interessant AR-eksperiment ved hjelp av Vuforia on Unity, men vi har fortsatt mange kule funksjoner for å dekke. Vi så ikke noen av de mer sofistikerte Vuforia-ressursene: Mål, Smart Terrain, Cloud, og så videre. Hold deg oppdatert for de neste opplæringsprogrammene, hvor vi dekker flere av disse funksjonene, og bruker alltid samme trinnvise tilnærming.
Ser deg snart!