Maak een Space Shooter met PlayCanvas deel 1

PlayCanvas maakt het heel eenvoudig om WebGL-powered, 3D-interactieve content voor het web te bouwen. Het is allemaal JavaScript, dus het werkt standaard in de browser zonder plug-ins. Het is een vrij jonge motor die pas sinds 2014 bestaat, maar die snel terrein wint met namen als Disney, King en Miniclip die games gebruiken om games te ontwikkelen. 

Het is een geweldige tool om twee belangrijke redenen: ten eerste is het een volledig uitgeruste game-engine, dus het behandelt alles, van afbeeldingen en botsingen tot audio en zelfs integratie met gamepads / VR. (U hoeft dus niet op externe bibliotheken te zoeken of u zorgen te maken over compatibiliteitsproblemen met de browser voor de meeste dingen.) De tweede, en waarvan ik denk dat deze er echt uitspringt, is hun browser-gebaseerde editor.

Dit is hoe een voorbeeldproject eruitziet in de browserinmaker van PlayCanvas. Het is een zeer krachtige en handige manier om uw werk te organiseren of zelfs in realtime samen te werken met anderen.

Als je gewend bent om met de Unity-engine te werken, moet de editor van PlayCanvas er bekend uitzien (er wordt zelfs een vergelijkbaar, op componenten gebaseerd systeem gebruikt voor het aaneenschakelen van functionaliteit). In tegenstelling tot Unity is PlayCanvas niet platformonafhankelijk en kan het alleen voor het web publiceren. Als het web echter alles is waar u om geeft, dan is dit een groot pluspunt, omdat de focus van de motor op internet het echt snel en licht maakt in vergelijking met de concurrentie.

Een laatste opmerking: hoewel de engine zelf gratis en open source is, de online editor en tools zijn alleen gratis voor openbare projecten.Het is zeker de moeite waard om voor te betalen als je er commercieel werk mee aan het ontwikkelen bent, maar je kunt het altijd gewoon als een puur codekader gebruiken en gratis gebruiken.. 

Het eindresultaat

Dit is wat we gaan maken:

U kunt een live demo uitproberen.

Het project zelf is openbaar, dus u kunt rondneuzen en / of doorvliegen op de projectpagina.

Je hoeft geen ervaring met 3D-spellen te hebben om mee te kunnen doen, maar ik ga ervan uit dat je wat vertrouwd bent met JavaScript.

Ons eigen project creëren van scratch

Het uiteindelijke resultaat is een relatief eenvoudige demo waarin je gewoon rondvliegt en asteroïden pusht, maar het biedt voldoende basisfunctionaliteit die nuttig is bij het maken van elk soort 3D-spel. Deel 1 behandelt de basisinstellingen, het werken met modellen, het physics-systeem en de camerabediening. Deel 2 behandelt het bullet-systeem, spaster asteroïden en het werken met tekst.

1. Projectinstelling 

Ga naar playcanvas.com en maak een account aan.

Zodra u bent ingelogd, klikt u op de projecten tab in het dashboard en druk op de grote sinaasappel nieuwe knop om een ​​nieuw project te maken. Dit zou het vak "nieuw project" moeten oproepen. Selecteer "leeg project" en geef het een naam:

Als je klaar bent, druk je op maak knop rechtsonder. Hiermee wordt u naar de projectoverzichtspagina gestuurd. Hier kunt u toegang krijgen tot uw instellingen en bijdragers toevoegen. Voor nu duiken we gewoon in het project, dus klik op de grote sinaasappel editor knop.

Wanneer je je eerste project binnengaat, laat PlayCanvas je veel hints zien over de editor. Je kunt die voorlopig negeren. De belangrijkste dingen om op te merken zijn:

  • Het linkerpaneel (hiërarchie) is een lijst met al uw wereldobjecten. Hier kunt u ook entiteiten uit uw scène toevoegen, dupliceren of verwijderen.
  • Het rechter (inspector) paneel is waar u de eigenschappen van het geselecteerde object bewerkt. Nadat u een object hebt geselecteerd (door erop te klikken), kunt u de positie en richting ervan instellen of scripts en componenten bijvoegen. 
  • Het onderste paneel (activa) bevat al uw activa. Hier kunt u zowel texturen als 3D-modellen uploaden en scripts maken.
  • In de middenscène kun je je gamewereld bewerken en bouwen. 

2. Een object maken

Als u een nieuw object in uw scène wilt maken, klikt u op de kleine plusknop boven in het hiërarchisch venster:

Opmerking: u kunt per ongeluk een nieuw object maken in een al bestaand object. Dit is handig voor het bouwen van objecten die uit meerdere delen bestaan ​​of die op de een of andere manier aan elkaar zijn verbonden. U kunt objecten in het hiërarchisch venster verplaatsen om het nesten te regelen. Sleep het naar de Wortel object om het terug te plaatsen bovenaan de hiërarchie. 

Als voorbeeld ga ik een nieuwe doos maken en deze rood kleuren. Om het een aangepaste kleur te geven, moeten we een nieuw materiaal maken. U kunt dit doen in het activapaneel, door met de rechtermuisknop ergens in het paneel te klikken of door op het kleine plusteken te klikken:

Eenmaal gemaakt, selecteert u uw materiaal en geeft u het een beschrijvende naam, zoals "RedMaterial" (u kunt het naamveld zien in het infovenster).

Blader nu naar beneden diffuus sectie en verander de kleur:

Als dat is gebeurd, gaat u terug en selecteert u het nieuwe vak dat u hebt gemaakt (door erop te klikken in de scène of in het hiërarchiepaneel). Stel vervolgens het materiaal in op het aangepaste materiaal dat we zojuist hebben gemaakt:

En de doos zou nu rood moeten zijn! Houd er rekening mee dat het materiaal dat u hebt gemaakt, aan zo veel objecten kan worden gekoppeld als u maar wilt.

3. Fysica toevoegen

Om fysica op een object in te schakelen, moeten we twee componenten toevoegen: Stijf lichaam en Botsing.

Voeg de Rigid Body toe door te klikken op "Add Component" in het infovenster van uw object:

Zorg ervoor dat het type is ingesteld op dynamisch:

En voeg op dezelfde manier een botsingcomponent toe. 

Start nu je spel door op de kleine afspeelknop rechtsboven in je scène te klikken. Je zou je kist door de vloer moeten zien vallen! Om dat te verhelpen, moet je ook een rigide lichaam en een botsing aan het vliegtuig toevoegen, waarbij je ervoor zorgt dat het stijve lichaamstype statisch is (zodat het niet zo goed valt). 

Uitdaging: probeer voor de lol een bol toe te voegen en het vlak iets te kantelen (op de X- of Z-as) om het te zien rollen.

Een opmerking over het componentsysteem

Het is de moeite waard om kort te praten over het componentsysteem, omdat het een fundamenteel onderdeel is van de architectuur van PlayCanvas. Conceptueel is het idee om functionaliteit van objecten te scheiden. Het grootste voordeel daarvan is het vermogen om complex gedrag uit kleinere modulaire componenten samen te stellen.

Als je bijvoorbeeld naar de camera kijkt in je scène, zul je merken dat het geen speciaal voorwerp is. Het is gewoon een generieke entiteit met een aangesloten camera-onderdeel. Je zou een camera-onderdeel aan alles kunnen bevestigen om er een camera van te maken, of een stijve body en een botsing aan de camera bevestigen om er een solide object van te maken (probeer het!). 

Als je nieuwsgierig bent, kun je meer lezen over de voor- en nadelen van componentsystemen op de Wikipedia-pagina.

4. Een model toevoegen

Nu u vertrouwd bent met de basis, kunnen we ons ruimtegame samenstellen. We hebben op zijn minst een schip en een asteroïde nodig om mee te werken. Er zijn twee manieren om modellen toe te voegen:

Pak een model uit de PlayCanvas-bibliotheek 

PlayCanvas heeft een winkel (vergelijkbaar met de Unity Asset Store in sommige opzichten) waar u activa direct in uw project kunt vinden en downloaden. Om toegang te krijgen, klikt u gewoon op bibliotheek in het activapaneel.

De winkel is erg nieuw, dus het is nogal schaars, maar het is een goede plek om tijdelijke aanduidingen of items te vinden om mee te experimenteren. 

Ik heb het hovership-item uit de winkel gebruikt als mijn spelersschip.

Upload uw eigen model

PlayCanvas ondersteunt wel het uploaden van FBX, OBJ, 3DS en COLLADA (DAE) bestanden, maar het geeft de voorkeur aan FBX. Je kunt elk 3D-model eenvoudig in FBX converteren door het met Blender te openen en het naar jouw gewenste formaat te exporteren.

Je kunt het asteroïdenmodel vinden dat ik op Blendswap.com gebruikte. Merk op dat je misschien je 3D-modellen wilt optimaliseren voordat je ze in de game gebruikt. Dat asteroïde-model bevat bijvoorbeeld meer dan 200.000 driehoeken! Dat is misschien goed voor een speciaal object in de game, maar toen ik er meer dan honderd asteroïden in de scène aan toevoegt, wordt het echt langzamer. Blender's Decimate-modifier is een eenvoudige manier om uw modellen te optimaliseren. Ik gebruikte dat om het asteroïde-model terug te brengen tot ongeveer 7.000 driehoeken zonder al te veel details te verliezen. 

Zodra de modellen zich in uw project bevinden (mogelijk moet u deze vernieuwen als u deze niet meteen in uw bedrijfsmiddelenpaneel ziet), kunt u ze aan uw scène toevoegen. De eenvoudigste manier om dat te doen, is door het model gewoon naar de scène te slepen:

Dit is het daadwerkelijke model zelf dat u aan de scène kunt toevoegen. De andere activa eromheen zijn de textuur / materiaal, enz.

Voeg, net als voorheen, een star lichaam en een aanvaringscomponent toe aan het schip. Een truc die je zou kunnen doen met een botsing is om de mesh van het eigenlijke object toe te voegen als zijn eigen botsingsvorm. Dit zou resulteren in een pixel-perfecte botsing mesh, maar zou niet erg efficiënt zijn. Voor deze demo koos ik voor een eenvoudige doos als mijn botsingvorm (en een bol voor de asteroïden) en bewerkte ik de half-mate om ongeveer overeen te komen met de vorm van het model.

De aanvaringsvorm verschuiven

Een probleem dat u tegen kunt komen bij het aanpassen van botsingsvormen, is het onvermogen om het te compenseren vanuit het midden. Een gemakkelijke manier om dit te omzeilen (afgezien van het moeten compenseren van het model zelf in zoiets als Blender voordat het wordt geëxporteerd) is om een ​​bovenliggend object te maken met de botsing en het starre lichaam en een kindobject dat het model zelf heeft. Dus je zou het model als kind kunnen verrekenen ten opzichte van de ouder die de botsing bevat. 

Dit is hoe ik het heb ingesteld voor het demoproject, dus je kunt daar een kijkje nemen om te zien hoe dat is gebeurd.

5. Veranderende zwaartekracht & scène-instellingen

Aangezien ons spel zich in de ruimte afspeelt, moeten we de standaardzwaartekracht opheffen. U kunt dit doen in de scène-instellingen. Helemaal links onderaan je scherm klik je op de tandwiel icoon. Dit opent de instellingen in het inspectievenster. Zoek de sectie Fysica en verander de zwaartekrachtwaarde:

Om zeker te zijn dat het werkte, probeer je het opnieuw te lanceren en kijk je of het schip slechts in de ruimte zweeft.

Het is niet echt ruimte zonder een sterrenachtergrond, dus terwijl we in de scene-instellingen zitten, voegen we een skybox toe. Je kunt er een kopen in de winkel of gewoon een online vinden die je leuk vindt. Zodra je het hebt, voeg je het toe in de rendering sectie:

Dat zou het spel een meer moeten geven vaag voelen. Dit zou ook een goed moment zijn om je scène op te schonen en alle testobjecten die we eerder hebben gemaakt te verwijderen.

6. Scripting the Ship

Dit is waar we eindelijk een code kunnen schrijven. Het scriptsysteem van PlayCanvas is een ander ding dat bekend zou moeten zijn als je Unity hebt gebruikt. U maakt scripts die aan elk object kunnen worden gekoppeld en deze scripts kunnen hebben attributen die per object zijn geconfigureerd. Scriptkenmerken zijn erg handig en bereiken twee belangrijke dingen:

  1. modulariteit. U kunt een script maken dat definieert hoe een vijand met een snelheidskenmerk beweegt en dat opnieuw gebruikt voor verschillende soorten vijanden met verschillende snelheden. 
  2. Samenwerking. Scriptkenmerken kunnen rechtstreeks in de editor worden aangepast zonder dat u een code hoeft aan te raken. Hierdoor kunnen ontwerpers zelf waarden aanpassen en tweaken zonder de programmeur lastig te vallen of code te doorzoeken. 

Maak een script

Ga naar het tabblad Activa en maak een nieuw activum van het type Script. Dit is de code voor het gedrag van het schip, dus noem het zoiets als "Vlieg". Dubbelklik erop om de scripteditor te openen.

De gebruikershandleiding van PlayCanvas is een zeer nuttige referentie bij het schrijven van scripts, net als de API-referentie. De automatische aanvulling maakt het ook heel gemakkelijk om erachter te komen welke methoden beschikbaar zijn. We beginnen met het draaien van ons schip. Typ dit in de bijwerken functie:

this.entity.rigidbody.applyTorque (0,1,0);

Binnen in elk script, deze verwijst naar de scriptcomponent zelf, terwijl this.entity verwijst naar het object waaraan het script is gekoppeld. U kunt op deze manier toegang krijgen tot alle onderdelen die aan de entiteit zijn gekoppeld. Hier hebben we toegang tot het stijve lichaam en oefenen we er een hoekige kracht op uit. 

Zorg ervoor dat je nu je script opslaat.

Voeg een script bij

Voordat ons script te betrokken raakt, voegen we het toe aan ons schip om te kijken of het werkt. Om dat te doen, voeg je gewoon een toe script component naar je schip en voeg daar dan je "vlieg" -script aan toe. Merk op dat u slechts één scriptcomponent per object kunt toevoegen, maar u kunt meerdere scripts binnen die component toevoegen.

Als je eenmaal bent gelanceerd, zou je je schip moeten zien draaien!

Voeg een kenmerk toe

Zoals hierboven besproken, maken scriptattributen onze code veel flexibeler. U kunt er een toevoegen door dit uit te typen bovenaan uw code, direct na de eerste regel waar het script is gemaakt:

Fly.attributes.add ('speed', type: 'number', default: 10, title: 'Ship Speed');

In dit geval is de naam van mijn script Vlieg. De enige vereiste optie is type.

Als u het attribuut in de editor wilt zien, gaat u terug naar uw scriptonderdeel en klikt u op het pictogram met twee pijlen in het fly-script. Dit is de ontleedknop die naar eventuele attributen zoekt en de editor bijwerkt. Uw component zou er nu als volgt uit moeten zien:

Tot slot, gewoon doen om de waarde van het attribuut in uw script te gebruiken deze. [ATTRIBUTE_NAME]. Dus als we wilden dat dit de draaisnelheid was, konden we onze coderegel wijzigen in:

this.entity.rigidbody.applyTorque (0, this.speed, 0);

Opmerking: aangezien er geen hoekdemping is, zal het schip sneller blijven draaien, hoe langer de kracht wordt uitgeoefend. Als u de kracht verwijdert, behoudt deze zijn traagheid en blijft deze met dezelfde snelheid draaien. Om dit te veranderen, stelt u de hoekdemping in de starre lichaamscomponent in op iets boven nul. 

Beweging met pijltoetsen

Nu willen we het script zo maken dat we het schip kunnen oriënteren met de pijltjestoetsen. Een naïeve benadering kan er als volgt uitzien:

Fly.prototype.update = function (dt) if (this.app.keyboard.isPressed (pc.KEY_RIGHT)) this.entity.rigidbody.applyTorque (0, this.speed, 0);  if (this.app.keyboard.isPressed (pc.KEY_LEFT)) this.entity.rigidbody.applyTorque (0, this.speed * -1,0);  if (this.app.keyboard.isPressed (pc.KEY_UP)) this.entity.rigidbody.applyTorque (this.speed * -1,0,0);  if (this.app.keyboard.isPressed (pc.KEY_DOWN)) this.entity.rigidbody.applyTorque (this.speed, 0,0); ;

Kun je vertellen wat het probleem is met dit script? Probeer het. Kunt u het schip eenvoudig wijzen waar u wilt?? 

Denk erover na voordat je verder leest. Hoe zou je dit oplossen??

Het probleem is dat we een kracht toepassen op globale coördinaten zonder rekening te houden met waar het schip tegenover staat. Als het schip horizontaal is ten opzichte van de camera en we draaien het op de y-as wanneer we op links / rechts drukken, dan roteert het correct. Maar als het schip verticaal staat, is een rotatie op de y-as nu een looprol.

Hetzelfde probleem zou gebeuren als we het schip ook naar voren zouden proberen te brengen. De richting die "vooruit" is, hangt af van waar het schip tegenover staat en kan niet absoluut zijn. 

Het is nu handig dat elke entiteit drie richtingsvectoren heeft die we kunnen gebruiken: omhoog, rechts, en vooruit. Om links / rechts te draaien, roteren we langs de omhoog as, en op en neer roteren we langs de rechts as. Dit zijn omhoog en rechts ten opzichte van de entiteit. Een vaste versie ziet er als volgt uit:

Fly.prototype.update = function (dt) var horizontalForce = this.entity.up.clone (); var verticalForce = this.entity.right.clone (); if (this.app.keyboard.isPressed (pc.KEY_RIGHT)) this.entity.rigidbody.applyTorque (horizontalForce.scale (this.speed * -1));  if (this.app.keyboard.isPressed (pc.KEY_LEFT)) this.entity.rigidbody.applyTorque (horizontalForce.scale (this.speed));  if (this.app.keyboard.isPressed (pc.KEY_UP)) this.entity.rigidbody.applyTorque (verticalForce.scale (this.speed * -1));  if (this.app.keyboard.isPressed (pc.KEY_DOWN)) this.entity.rigidbody.applyTorque (verticalForce.scale (this.speed)); ;

Voorwaartse beweging toevoegen is hetzelfde idee:

if (this.app.keyboard.isPressed (pc.KEY_Z)) this.entity.rigidbody.applyForce (this.entity.forward.clone (). scale (-1)); 

Als de beweging te glad of te glad aanvoelt, besteed dan wat tijd aan het aanpassen van de snelheden en dempingsfactoren om het naar de plaats te brengen waar het goed voelt.

7. Camerabediening 

Het is moeilijk om een ​​bewegend schip met een vaste camera bij te houden. De eenvoudigste manier om de camera een object te laten volgen, is door de camera als een kind van dat object te plaatsen.

Sleep de camera in het hiërarchisch paneel naar uw schip. Een handige manier om de weergave van de camera aan te passen, is door in de scène over te schakelen naar de weergave van die camera. Klik op de knop boven aan het scherm waar deze staat Perspectief. Dit geeft je een vervolgkeuzemenu met alle verschillende scèneweergaven die je kunt selecteren. kiezen Camera, welke het verste zou moeten zijn. Dit is een speciale weergave, want wat je ook in de editor ziet, is wat de camera in de game te zien krijgt. 

Nadat u de weergave van de camera hebt aangepast, moet u terugschakelen naar het perspectief of een andere weergave om te voorkomen dat de camerahoeken per ongeluk vervuild raken.

Tip: Als u een object hebt geselecteerd in de hiërarchie, maar u het niet in uw scène kunt vinden, drukt u op F. Hiermee wordt de weergave op dat object gefocust en wordt erop ingezoomd. Je kunt meer sneltoetsen bekijken door op de toetsenbordknop helemaal links op je scherm te klikken.

Op dit punt zou je een camera moeten hebben die je schip volgt (hoe stijf hij ook is). (Je zult niet weten of je beweegt als de camera beweegt en er zijn geen andere objecten in de wereld, dus probeer wat toe te voegen.)

Camerascripts

Een camera die net op de speler is geplakt, is niet erg interessant. Deze post op het PlayCanvas-blog verkent verschillende soorten camerabewegingen. De eenvoudigste die we kunnen implementeren is de kijk naar de camera.

Om dit te doen, moet u de camera eerst terugzetten naar het hoofdobject. 

Maak vervolgens een nieuw script genaamd kijk naar

De updatefunctie van dat script moet er als volgt uitzien:

LookAt.prototype.update = function (dt) this.entity.lookAt (this.target.getPosition ()); ;

En het zou een attribuut moeten hebben:

LookAt.attributes.add ('target', type: 'entity');

Bevestig dat script nu aan het cameraobject. Druk op de ontleedknop en stel het doel in als de scheepsentiteit.

Probeer te lanceren! Als alles goed is gegaan, blijft je camera op zijn plaats zitten maar richt je je gewoon op het schip.

U kunt de andere typen camera's op dezelfde manier implementeren. De volg camera volgen vermeld in de blogpost ziet er idealiter het mooist uit, maar ik vond het te zenuwachtig wanneer de framerate een beetje dompelde, dus voor de definitieve demo ging ik uiteindelijk met een camera die als kind aan het schip was bevestigd, maar gescript om te bewegen en draaien zoals het schip deed.

Conclusie

Maak je geen zorgen als iets hiervan een beetje overweldigend voelt. PlayCanvas is een complexe motor met veel toeters en bellen. Er is veel te ontdekken, en het bij de hand houden van de handleiding is een goede manier om je te oriënteren. Een andere goede manier om te leren is door openbare projecten te vinden en te kijken hoe de dingen zijn gemaakt.

Deel 2 begint met het maken van een kogelsysteem en het toevoegen van een aantal asteroïden om op te schieten, en we vullen het af met een FPS-teller en tekst in de game. Als u vragen of suggesties hebt of als er iets onduidelijk is, laat het me dan weten in de reacties!