Forstå styringsadferd Sti etter

Sti som følger er et hyppig problem i spillutvikling. Denne opplæringen dekker sti følgende styringsadferd, som lar tegnene følge en forhåndsdefinert sti laget av punkter og linjer.

Merk: Selv om denne opplæringen er skrevet med AS3 og Flash, bør du kunne bruke de samme teknikkene og konseptene i nesten hvilket som helst spillutviklingsmiljø. Du må ha en grunnleggende forståelse av matematiske vektorer.


Introduksjon

En sti som følger oppførsel kan implementeres på flere måter. Den originale Reynolds-implementasjonen bruker en strekning av linjer, der tegn følger dem strengt, nesten som et tog på skinner.

Avhengig av situasjonen kan det ikke være nødvendig med presisjon. Et tegn kan bevege seg langs en sti som følger linjer, men bruker dem som en henvisning, heller enn som skinner.

Gjennomføringen av banen som følger oppførsel i denne opplæringen er en forenkling av den opprinnelige som Reynolds foreslår. Det produserer fortsatt gode resultater, men det stole ikke på tunge matematiske beregninger som vektorprojeksjoner.


Definere en sti

En sti kan defineres som et sett med poeng (noder) forbundet med linjer. Selv om kurver også kan brukes til å beskrive en bane, er poeng og linjer lettere å håndtere og produserer nesten de samme resultatene.

Hvis du trenger å bruke kurver, kan de reduseres til et sett med tilkoblede punkter:


Kurver og linjer.

Klassen Sti vil bli brukt til å beskrive ruten. I utgangspunktet har klassen en vektor av poeng og noen få metoder for å administrere den listen:

 offentlig klasse Path private var noder: Vector.; offentlig funksjon Sti () this.nodes = ny vektor.();  offentlig funksjon addNode (node: Vector3D): void nodes.push (node);  offentlig funksjon getNodes (): Vector. retur noder; 

Hvert punkt i stien er a Vector3D som representerer en posisjon i rommet, på samme måte som tegnet er stilling eiendom fungerer.


Flytter fra Node til Node

For å navigere tenkte banen, vil tegnet bevege seg fra knutepunkt til knutepunkt til den når slutten av ruten.

Hvert punkt i stien kan sees som et mål, så søkegraden kan brukes:

Søk et poeng etter det andre.

Tegnet vil søke det nåværende punktet til det er nådd, og neste punkt i banen blir nåværende og så videre. Som tidligere beskrevet i kollisionsvurderingsopplæringen, beregnes hver opptredenes krefter igjen hver spilloppdatering, slik at overgangen fra en node til en annen er sømløs og glatt.

Karakterens klasse vil trenge to ekstra egenskaper til instrumentet navigasjonsprosessen: den nåværende noden (den ene karakteren søker) og en referanse til banen som følges. Klassen vil se ut som følgende:

 offentlig klasse Boid public var path: Sti; offentlig var currentNode: int; (...) privat funksjonsveiFølgende (): Vector3D var mål: Vector3D = null; hvis (bane! = null) var noder: Vector. = path.getNodes (); target = noder [currentNode]; hvis (avstand (posisjon, mål) <= 10)  currentNode += 1; if (currentNode >= nodes.length) currentNode = nodes.length - 1;  returnere null;  privat funksjonsavstand (a: Objekt, b: Objekt): Nummer Return Math.sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));  (...)

De pathFollowing () Metoden er den som er ansvarlig for å generere stien som følger med kraften. For tiden produserer det ingen kraft, men det velger målene riktig.

De sti! = null test sjekker om tegnet følger en hvilken som helst bane. Hvis det er tilfelle, currentNode Egenskapen brukes til å slå opp det nåværende målet (det tegnet må søke) i listen over punkter.

Hvis avstanden mellom nåværende mål og tegnets posisjon er mindre enn 10, det betyr at tegnet har nådd nåværende knutepunkt. Hvis det skjer, currentNode økes med en, noe som betyr at tegnet vil søke neste punkt i banen. Prosessen gjentas til banen går tom for punkter.


Beregne og legge til styrker

Kraften som brukes til å skyve tegnet mot hver knutepunkt i banen, er søkekraften. De pathFollowing () Metoden velger allerede riktig knutepunkt, så nå må den returnere en kraft som vil presse tegnet mot den knutepunktet:

 privat funksjonsveiFølgende (): Vector3D var mål: Vector3D = null; hvis (bane! = null) var noder: Vector. = path.getNodes (); target = noder [currentNode]; hvis (avstand (posisjon, mål) <= 10)  currentNode += 1; if (currentNode >= nodes.length) currentNode = nodes.length - 1;  returmål! = null? søke (mål): Ny Vector3D (); 

Etter at banen etter kraft er beregnet, må den legges til karakterens hastighetsvektor som vanlig:

 styring = ingenting (); // null-vektoren, som betyr "nullstyrke" styring = styring + pathFollowing (); styring = trunkering (styring, maks_force) styring = styring / massehastighet = trunkering (hastighet + styring, maks_speed) posisjon = posisjon + hastighet

Stien som følger styrestyrken, er ekstremt lik forfølgelsesadferansen, der tegnet kontinuerlig justerer sin retning for å fange målet. Forskjellen ligger i hvordan karakteren søker et fast mål, som ignoreres til fordel for en annen så snart karakteren blir for nær.

Resultatet er følgende:

Sti følge i handling. Klikk for å vise styrker.

Utjevne bevegelsen

Den nåværende implementeringen krever at alle tegnene "berører" det nåværende punktet i banen for å velge neste mål. Som et resultat kan et tegn utføre uønskede bevegelsesmønstre, for eksempel å flytte i sirkler rundt et punkt til det er nådd.

I naturen har hver bevegelse en tendens til å adlyde prinsippet om minste innsats. For eksempel vil en person ikke gå i midten av en korridor hele tiden; hvis det er en tur, vil personen gå tett til veggene mens du svinger for å forkorte avstanden.

Det mønsteret kan gjenskapes ved å legge til en radius på banen. Radien påføres punktene, og den kan ses som ruten "bredde". Det vil kontrollere hvor langt et tegn kan bevege seg fra punktene underveis:

Innflytelse av radius på sti som følger.

Hvis avstanden mellom tegnet og punktet er mindre enn eller lik radius, anses punktet nådd. Som en konsekvens vil alle tegn bevege seg ved hjelp av linjene og poengene som guider:

Sti følger med radius. Klikk på "Force" knappen for å vise krefter. Klikk på knappene "+" og "-" for å justere radiusstørrelsen dynamisk.

Jo større radius, jo bredere ruten og jo større avstanden som tegnene vil holde fra punktene når de snu. Verdien av radiusen kan tweaked for å produsere forskjellige følgende mønstre.


Går tilbake og fremover

Noen ganger er det nyttig for et tegn å fortsette å bevege seg etter at det når slutten av banen. I et patruljemønster, for eksempel, skal karakteren gå tilbake til begynnelsen av ruten etter at den når slutten, etter de samme punktene.

Dette kan oppnås ved å legge til pathDir eiendom til karakterens klasse; dette er et heltall som styrer retningen der tegnet beveger seg langs banen. Hvis pathDir er 1, det betyr at tegnet beveger seg mot slutten av banen; -1 betegner en bevegelse mot starten.

De pathFollowing () Metoden kan endres til:

 privat funksjonsveiFølgende (): Vector3D var mål: Vector3D = null; hvis (bane! = null) var noder: Vector. = path.getNodes (); target = noder [currentNode]; hvis (avstand (posisjon, mål) <= path.radius)  currentNode += pathDir; if (currentNode >= nodes.length || currentNode < 0)  pathDir *= -1; currentNode += pathDir;    return target != null ? seek(target) : new Vector3D(); 

I motsetning til den eldre versjonen, verdien av pathDir er nå lagt til eiendommen currentNode (i stedet for å bare legge til 1). Dette tillater tegnet å velge neste punkt i banen basert på den aktuelle retningen.

Deretter sjekker en test om karakteren har nådd slutten av ruten. Hvis det er tilfelle, pathDir multipliseres med -1, som inverts sin verdi, slik at karakteren inverterer bevegelsesretningen også.

Resultatet er et frem og tilbake bevegelsesmønster:

Sti etter med radius og frem og tilbake mønster. Klikk på "Force" knappen for å vise krefter. Klikk på knappene "+" og "-" for å justere radiusstørrelsen dynamisk.

Konklusjon

Stien som følger oppførsel tillater at et tegn kan bevege seg langs en forhåndsdefinert bane. Ruten styres av poeng, og den kan justeres for å være bredere eller smalere, og produsere bevegelsesmønstre som føles mer naturlige.

Implementeringen som omfattes av denne opplæringen, er en forenkling av den opprinnelige stien etter atferd foreslått av Reynolds, men det gir fortsatt overbevisende og tiltalende resultater.