Den ultimative begyndere guide til spiludvikling i enhed

Enhed er et fantastisk værktøj til prototypering af alt fra spil til interaktive visualiseringer. I denne artikel gennemgår vi alt hvad du behøver at vide for at komme i gang med at bruge Unity.

Først en lille smule om mig: Jeg er en hobbyudvikler, 3d-modelør og grafisk designer, der har arbejdet med Unity og Blender i over 5 år. Jeg er nu en finansiel matematikstudent ved University College Dublin, og lejlighedsvis laver jeg freelance grafisk design, webprototypning og spilprototypning.

Introduktion

Denne artikel henvender sig til alle, der aldrig har brugt Unity før, men som har tidligere erfaring med programmering eller inden for webdesign / udvikling. I slutningen af ​​denne artikel skal du have et godt generelt overblik over motoren samt alle de nødvendige funktioner og kode for at begynde at lave et grundlæggende spil.

Hvorfor enhed?

Hvis du vil lave spil

Der er virkelig meget få muligheder, når det kommer til Indie Game-udvikling. De tre vigtigste valg, hvis du vil bygge spil, er Unreal, Unity eller GameMaker.

Enhed er sandsynligvis den mindst opfattede af de tre platforme. Det giver dig et meget rå produkt ud af kassen, men er meget fleksibelt, veldokumenteret og meget udvideligt til at opbygge stort set enhver genre af spil, du kan tænke på.

Der er masser af meget succesrige spil som Escape from Tarkov (FPS), Monument Valley (Puzzler) og This War of Mine (Strategy / Survival), der alle er bygget i Unity.

I virkeligheden er den motor, du bygger dit første spil på, sandsynligvis ikke kritisk, så mit råd er bare at vælge en og gå med den.

Hvis du vil prototype brugeroplevelser

Da enhed bare er en motor med en masse fysik, animation og 3D-gengivelse i realtid, er det også et godt sted at lave fuldt udviklede interaktive prototyper til UX-studier.

Unity har fuld støtte til VR og AR og kan derfor være et godt værktøj til at udforske arkitektur, automatiseringer og simuleringer med klienter.

Afsnit til denne artikel

  • Hvorfor enhed?
  • Vinduet Enhedsredaktør
  • Unity Game Objects
  • Enhedsindbyggede komponenter
  • Oprettelse af brugerdefinerede komponenter
  • Opbygning af en monobedrift
  • Manipulerer GameObjects
  • Raycasting
  • Kollisionsdetektion
  • Avancerede egenskaber
  • Rådgivning til nybegyndere
  • Dejlige ressourcer og samfund
  • Konklusion

Vindue til enhedseditor

Editor-vinduet er opdelt i et par sektioner. Vi vil dække dette meget kort, da vi konstant henviser til det gennem hele artiklen. Hvis du er fortrolig med dette, skal du bare springe forbi!

Scene View: Tillader placering og bevægelse af GameObjects i Scene Game View: Previews hvordan afspilleren vil se scenen fra kameraet Inspektør: Angiv detaljer om det valgte GameObject i scenen. Aktiver / projekt: Alle præfabrikker, strukturer, modeller, scripts osv. Er gemt her. Hierarki: Aktiverer indlejring og strukturering af GameObjects inden for scenen

Nu er vi gode til at starte!

Unity Game Objects

Hvad er GameObjects

GameObjects er den grundlæggende byggesten i alt i Unity-spilmotoren. Navnet giver det næsten væk:

Alt, hvad du placerer inden for en scene i Unity, skal pakkes ind i et 'spilobjekt'.

Hvis du har en webdesignbaggrund, kan du tænke på GameObjects som meget lignende elementer! Ekstremt kedelige containere, men er meget udvidelige til at skabe kompleks funktionalitet eller visuals.

Bogstaveligt talt er alt fra partikeleffekter, kameraer, afspillere, UI-elementer ... (listen fortsætter) et GameObject.

Oprettelse af hierarki

Som en i webudvikling er en GameObject også en container. Ligesom du nestes for at skabe varierede og ønskelige layouter eller abstraktioner, kan du muligvis gøre det samme med spilgenstande.

Logikken bag indlejring af spilobjekter er meget den samme som webudvikling, jeg giver et par eksempler ...

Rod & effektivitet

Webanalogi: Du har mange lignende elementer, som kan genereres dynamisk i farten som reaktion på brugerinteraktion og ønsker at holde dem pæne. Enhedsoversættelse: Din bygning af en Minecraft-klon, og du har masser af blokke i scenen, du skal tilføje og fjerne 'klumper' af blokke fra scenen af ​​ydeevneårsager. Således er det fornuftigt at have dem parenteret til et tomt GameObject for hvert stykke, da det at fjerne forældren fjerner alle børneblokkene.

Positionering

Webanalogi: Du vil bevare placeringen af ​​det indeholdte indhold 'relativt' i forhold til containeren og ikke til websiden. Enhedsoversættelse: Du har oprettet en masse hjælperdroner, der svæver rundt om afspilleren. Du vil virkelig ikke hellere skrive kode for at fortælle dem, at de skal jage efter afspilleren, så i stedet instantierer du dem som børn af afspillerens objekt.

Enhedsindbyggede komponenter

Skuespillerens komponentmodel

GameObjects alene er ret ubrugelige - som vi har set, er de stort set bare containere. For at tilføje funktionalitet til dem er vi nødt til at tilføje komponenter, som i det væsentlige er scripts skrevet i enten C # eller Javascript.

Enhed fungerer ud fra en Actor Component-model, simpelthen sagt, GameObjects er skuespillerne, og komponenterne er dine scripts.

Hvis du har skrevet nogen webapps før, vil du være fortrolig med ideen om at oprette små genanvendelige komponenter som knapper, formelementer, fleksible layout, der har forskellige forskellige direktiver og tilpasselige egenskaber. Derefter samles disse små komponenter i større websider.

Den store fordel ved denne tilgang er niveauet for genanvendelighed og klart definerede kommunikationskanaler mellem elementer. Ligeledes i spiludvikling ønsker vi at minimere risikoen for utilsigtede bivirkninger. Små bugs har en tendens til at gå ud af kontrol, hvis du ikke er forsigtig og er ekstremt vanskelig at fejle. Det er derfor afgørende at skabe små, robuste og genanvendelige komponenter.

Nøgleindbyggede komponenter

Jeg synes, det er tid til et par eksempler på de indbyggede komponenter leveret af Unity Games-motoren.

  • MeshFilter: Giver dig mulighed for at tildele materialer til et 3D-mesh til et GameObject
  • MeshRender: Giver dig mulighed for at tildele materialer til et 3D Mesh
  • [Ramme | Mesh] Collider: Aktiverer detektion af GameObject under kollisioner
  • Rigidbody: Gør det muligt for realistisk fysisk simulering at handle på GameObjects med 3d Meshes og vil være triggerdetekteringshændelser på box colliders
  • Lys: Lyser dele af din scene
  • Kamera: Definerer den afspiller, der skal knyttes til et GameObject
  • Forskellige UI lærredskomponenter til visning af GUI'er

Der er masser mere, men disse er de vigtigste, du bliver nødt til at blive fortrolig med. Et tip er, at du kan få adgang til alle dokumenter til disse gennem enhedsmanualen og scriptreferencen offline, uanset hvor du er:

Oprettelse af brugerdefinerede komponenter

De indbyggede komponenter styrer primært fysik og grafik, men for virkelig at lave et spil bliver du nødt til at acceptere brugerinput og manipulere disse standardkomponenter såvel som GameObjects selv.

For at begynde at oprette komponenter skal du gå ind i det ønskede GameObject> Tilføj komponent> skriv navnet på din nye komponent i søgefeltet> nyt script (c #).

Som en generel anbefaling vil jeg fraråde brug af Javascript in Unity. Det er ikke blevet opdateret med alle de fantastiske ting, der fulgte med ES6, og de fleste af de mere avancerede ting er afhængige af C #-ting, der overføres til Javascript ... Det bliver bare en kæmpe løsning i min erfaring.

Opbygning af en monobedrift

Nøglefunktioner

Alle komponenter arver fra MonoBehaviour-klassen. Det inkluderer flere standardmetoder, vigtigst af alt:

  • ugyldigt Start (), der kaldes, når et objekt, der indeholder scriptet, instantieres i scenen. Dette er nyttigt når som helst vi vil udføre en initialiseringskode, f.eks. indstil en spillers udstyr, når de gyder i en kamp.
  • ugyldig opdatering (), der kaldes hver ramme. Det er her, hovedparten af ​​koden, der involverer brugerinput, går hen, opdaterer forskellige egenskaber såsom afspillerens bevægelse i scenen.

Inspektørvariabler

Ofte vil vi gøre komponenter så fleksible som muligt. For eksempel kan alle våben have forskellige skader, skudhastighed, has_sight osv. Mens alle våben i det væsentlige er de samme ting, vil vi muligvis hurtigt kunne skabe forskellige variationer gennem enhedseditoren.

Et andet eksempel, hvor vi måske vil gøre dette, er når vi opretter en UI-komponent, der sporer brugermusebevægelser og placerer en markør i visningen. Her vil vi måske kontrollere markørens følsomhed over for bevægelser (hvis brugeren brugte et joystick eller gamepad vs en computermus). Således ville det være fornuftigt at have disse variabler lette at ændre både i redigeringstilstand og også eksperimentere med dem under kørsel.

Vi kan gøre dette let ved blot at erklære dem som offentlige variabler i komponentens krop.

Accepterer brugerinput

Selvfølgelig vil vi have, at vores spil reagerer på brugerinput. De mest almindelige måder at gøre det på er ved hjælp af følgende metoder i Update () -funktionen på en komponent (eller andre steder, du kan lide):

  • Input.GetKey (KeyCode.W) Returnerer True W-tasten holdes nede
  • Input.GetKeyDown (KeyCode.W) Returnerer True, når der trykkes på W-tasten
  • Input.GetAxis (“Lodret”), Input.GetAxis (“Vandret”) Returnerer mellem -1,1 muses inputbevægelse

Manipulerer GameObjects

Når vi har fået input fra brugerne, vil vi have GameObjects inden for vores scene til at svare. Der er flere typer svar, vi kan overveje:

  • Oversættelse, rotation, skala
  • Opret nye GameObjects
  • Afsendelse af beskeder til eksisterende GameObjects / komponenter

Transformationer

GameObjects har alle en transform-egenskab, der gør det muligt at udføre forskellige nyttige manipulationer på det aktuelle spilobjekt.

Ovennævnte metoder er ret selvforklarende, bemærk bare at vi bruger små bogstaver gameObject til at henvise til GameObject, som ejer denne specifikke forekomst af komponenten.

Generelt er det en god praksis at bruge lokal [Position, Rotation] snarere end den globale position / rotation af et objekt. Dette gør det normalt lettere at flytte objekter på en måde, der giver mening, da den lokale rumakse vil være orienteret og centreret på det overordnede objekt i stedet for verdens oprindelse og x, y, z retninger.

Hvis du har brug for at konvertere mellem lokalt og verdensrum (hvilket ofte er tilfældet) kan du bruge følgende:

Som du kan forestille dig, er der nogle ret enkle lineære algebra bag dette antydet af 'Inverse' i metodens navn.

Oprettelse af nye GameObjects

Da GameObjects stort set er alt i din scene, vil du måske være i stand til at generere dem på farten. For eksempel, hvis din afspiller har en slags projektil launcher, kan du muligvis være i stand til at oprette projektiler på farten, der har deres egen indkapslede logik til flyvning, håndtering af skader osv ...

Først skal vi introducere forestillingen om en præfabrik . Vi kan oprette disse ved blot at trække et hvilket som helst GameObject i scenehierarkiet til aktivmappen.

Dette gemmer i det væsentlige en skabelon for det objekt, vi lige havde i vores scene med alle de samme konfigurationer.

Når vi først har disse præfabrikerede komponenter, kan vi tildele dem til inspektørvariabler (som vi talte om tidligere) på enhver komponent i scenen, så vi til enhver tid kan oprette nye GameObjects som specificeret af præfabrikken.

Vi kan derefter udføre 'instantiering' af præfabrikken og manipulere den til det ønskede sted i scenen og etablere de nødvendige forældrerelationer.

Adgang til andre GameObjects og komponenter

Ofte har vi brug for at kommunikere med andre GameObjects såvel som deres tilknyttede komponenter. Når du først har en henvisning til et spilobjekt, er dette ret simpelt.

ComponentName comp = some_game_object.GetComponent ();

Derefter kan du få adgang til en hvilken som helst af de offentlige metoder / variabler for komponenten for at manipulere GameObject. Dette er den ligefremme bit, men faktisk at opnå en henvisning til GameObject kan ske på flere måder ...

Adgang via inspektørvariabel

Dette er det mest ligetil. Opret blot en offentlig variabel til GameObject, som vi tidligere har demonstreret med præfabrikkerne, og træk og slip den manuelt på komponenten via inspektøren. Gå derefter til variablen som ovenfor.

Adgang via tagging

Vi kan tagge GameObjects eller prefabs via inspektøren og derefter bruge funktionerne til find spilobjekter til at finde referencer til dem.

Dette gøres simpelthen som nedenfor.

GameObject some_game_object = GameObject.FindGameObjectWithTag (“Brick”);

Adgang via transform

Hvis vi ønsker at få adgang til komponenter i et overordnet objekt, kan vi nemt gøre dette via transformattributten.

ComponentName comp = gameObject.transform.parent.GetComponent ();

Adgang via SendMessage

Alternativt, hvis vi ønsker at sende en besked til mange andre komponenter eller ønsker at sende en besked til et objekt, der er langt op i et indlejret hierarki, kan vi bruge send beskedfunktionerne, der accepterer navnet på funktionen efterfulgt af argumenterne.

gameObject.SendMessage (“MethodName”, params); // Broadcast messagegameObject.SendMessageUpwards (“MethodName”, params); // Modtages kun af komponenter, der er indlejret ovenfor.

Raycasting

Du har måske hørt om dette før, når folk sammenligner FPS-spil, der er 'fysikbaseret' eller 'strålebaseret'. Raycasting er i det væsentlige som at have en laserpeger, som når den kommer i kontakt med en 'kollider' eller 'stiv krop', returnerer den et 'hit' og videregiver detaljerne i objektet.

Der er to scenarier, hvor dette er nyttigt (Der er sandsynligvis masser mere):

  1. Hvis du designede et våbensystem til et spil, kunne du bruge raycasting til hitdetektering og endda tilpasse længden af ​​strålen, så nærkampsposter kun "ramte" i korte intervaller
  2. Opret en stråle fra musemarkøren til et punkt i 3d-rum, dvs. hvis du ønsker, at brugeren skal kunne vælge enheder med deres mus i et strategispil.

Som du kan se, er koden for dette lidt mere involveret. Det vigtigste at forstå er, at for at kaste en stråle til, hvor musen peger i 3d-rum, kræves ScreenPointToRay-transformation. Årsagen til dette er, at kameraet gengiver et 3d-rum som en 2d-visning på din bærbare pc-skærm, så naturligvis er der en projektion involveret for at overføre tilbage til 3d.

Kollisionsdetektion

Tidligere nævnte vi komponenterne Collider og Rigidbody, som kan føjes til et objekt. Reglen for kollisioner er, at det ene objekt i kollisionen skal have et stift legeme og det andet en kolliderende (eller begge har begge komponenter). Bemærk, at når du bruger raycasting, vil stråler kun interagere med objekter med monterede collider-komponenter.

Efter installation inden for en hvilken som helst brugerdefineret komponent, der er knyttet til objektet, kan vi bruge metoderne OnCollisionEnter, OnCollisionStay og OnCollisionExit til at reagere på kollisioner. Når vi har kollisionsoplysningerne, kan vi få GameObject ansvarlige og bruge det, vi lærte tidligere, til at interagere med komponenter, der er knyttet til det også.

En ting at bemærke er, at stive kroppe leverer fysik som tyngdekraft for objekter, så hvis du vil have dette slået fra, skal du kontrollere is_kinematic .

Avancerede egenskaber

Vi går ikke ind på noget af dette nu, men måske i en fremtidig artikel - bare for at gøre dig opmærksom på, at de eksisterer.

Oprettelse af GUI'er

Unity har en fuldt udbygget UI-motor til at lægge GUI ud til dit spil. Generelt fungerer disse komponenter stort set på samme måde som resten af ​​motoren.

Udvidelse af Unity Editor

Enhed giver dig mulighed for at tilføje brugerdefinerede knapper til dine inspektører, så du kan påvirke verden under redigeringstilstand. For at hjælpe med verdensopbygning kan du f.eks. Udvikle et brugerdefineret værktøjsvindue til opbygning af modulære huse.

Animation

Unity har et grafbaseret animationssystem, der giver dig mulighed for at blande og kontrollere animationer på forskellige objekter, såsom spillere, der implementerer et benbaseret animationssystem.

Materialer og PBR

Enhed kører fra en fysisk baseret gengivelsesmotor, der muliggør belysning i realtid og realistiske materialer. Virkeligheden er, at du enten skal lære 3d-modellering først eller bruge modeller, der er lavet og optimeret af en anden, før du kommer til dette, for at lave ting, der rent faktisk ser godt ud.

Rådgivning til nybegyndere

Hvis du planlægger at skrive dit første spil, skal du ikke undervurdere kompleksiteten og tiden det tager at skrive selv det mest trivielle spil. Husk de fleste af de spil, der kommer ud på Steam, har hold, der arbejder på dem i årevis på fuld tid!

Vælg et simpelt koncept, og opdel det i små opnåelige milepæle. Det anbefales stærkt at adskille dit spil i så små uafhængige komponenter som muligt, da det er meget mindre sandsynligt, at du løber ind i fejl, hvis du holder komponenterne enkle snarere end monolitiske kodeblokke.

Inden du går og skriver en kode til en hvilken som helst del af dit spil, skal du undersøge, hvad en anden har gjort før for at løse det samme problem - chancerne er, at de får en meget glattere løsning.

Dejlige ressourcer og samfund

Spilledesign har et af de bedste samfund derude, og der er masser af højt kvalificerede professionelle i branchen, der stiller indhold gratis eller næsten ingenting. Det er et felt, der kræver 3d-modellerere, konceptkunstnere, spildesignere, programmører osv. Jeg har knyttet nogle gode generelle ressourcer, som jeg er stødt på for hvert af disse felter nedenfor:

Konceptkunst

  • Feng Zhu Design School (Over 90 timers lange tutorials i konceptkunst)
  • Tyler Edlin Art (Fantastisk BST-kunstsamfund med feedback fra professionelle om månedlige udfordringer)
  • Art Cafe (Interviews og workshops med berømte konceptkunstnere)
  • Trent Kaniuga (Illustrator og 2D-kunstner, der også laver sit eget spil)

3D-modellering

  • CG Cookie (de bedste basismetoder til netmodellering i blender nogensinde, de har masser af andet fremragende indhold til blender)
  • Tor Frick (hårde overflademodeller og billedhuggere i blender)
  • Gleb Alexandrov (Kort kraftfuld gengivelsesvejledning i Blender)

Spil Design

  • DoubleFine Amnesia Fortnight (GameDevs der laver en 2 ugers hackathon og registrerer hele deres designproces)
  • GameMakers Toolkit (undersøger principper for spildesign)

Programmering

  • Håndlavet helt (skriver et spil og en motor fra bunden i C)
  • Jonathan Blow (Indie-dev, der livestreamer sin spiludvikling)
  • Brackeys (Nice Unity Tutorials)

Konklusion

Håber I kunne lide denne tutorial! Jeg laver lidt grafisk design såvel som spil og UI prototyper, så tjek min portefølje ! Jeg er også tilknyttet .

Portefølje| LinkedIn