Bemærk: Det antages at du bruger player-scriptet fra Standard Assets, ligesom i resten af denne artikelserie. Hvis dette ikke er tilfældet, er du muligvis nødt til at ændre i template-koden for at tilpasse den til dit player-script.
Download og integration i Unity-projekt
For at kunne bruge FPS Templates i dit Unity-projekt, skal du downloade det, og lægge det ind i projektet.
Du kan downloade det fra github: github.com/Sioniras/FPSTemplates. Tryk på knappen Code og vælg Download ZIP, eller tryk her.
Gå til Assets-mappen i project-panelet i Unity, højre-klik på f.eks. Scripts-mappen og vælg Show in Explorer. Så skulle Windows' Stifinder åbne i Assets-mappen. Du kan nu finde mappen NighthawkFPSTemplates i en undermappe i den zip-fil, som du har downloaded, og kopiere den over i Assets-mappen for dit Unity-projekt.
Dette er illustreret her:
Når du nu kigger i Project-panelet i Unity skulle du gerne have NighthawkFPSTemplates-mappen:
Opsætning af FPS Templates
For at bruge template-koden skal der først laves en lille smule opsætning. Start med at højre-klikke i scene-hierarkiet og lav et tomt GameObject (Create Empty). Kald det nye objekt "GameManager", og flyt det op så det ligger øverst i scene-hierarkiet (så det er nemt at finde senere).
I project-panelet kan du finde scriptet GameController i mappen Assets -> NighthawkFPSTemplates -> Scripts. Træk GameController-scriptet ud på GameManager-objektet.
Nu kan du trække dit player-objekt i scene-hierarkiet (FPSController) over på "Player"-feltet i GameController-scriptet. Dermed er den vigtigste del af opsætningen klaret:
I project-panelet kan du nu finde mappen Assets -> NighthawkFPSTemplates -> Prefabs. Her ligger der et prefab kaldet UI, som du kan trække op i scene-hierarkiet. Du kan f.eks. lægge det som et under-objekt til GameManager.
Der skal sættes to referencer på din GameManager (GameController-komponent) fra den UI-prefab du nu har i scenen. Det er GameOverPanel og MessageFieldText som skal trækkes fra scene-hierarkiet over på de tilsvarende felter i GameController-komponenten.
Det ser således ud:
Nu er du klar til at starte dit spil igen! Der er nu kommet et sigtekorn midt på skærmen, og visning af ammunition nederst til højre. Hvis du krydser "Player can die" af på GameManager-objektet vil du også se et tal nederst til venstre, der viser hvor meget liv du har:
Hvis du vil skjule sigtekorn eller ammo-display kan du vælge Crosshair- eller AmmoDisplay-objektet i scenen, og slå det fra aller-øverst i properties-panelet (Inspector).
Du er nu klar til at bruge template-koden! Der er mange indstillinger i GameManager (GameController-scriptet) som stadig kan sættes, f.eks. til opsætning af våben, men det ser vi på senere i en anden artikel.
Her vil vi i stedet fortsætte med at se, hvordan enkelte template-scripts kan bruges.
Door-scriptet: Meget mere end en dør!
I first-person-skydespil som foregår indenfor, er der typisk mange døre - derfor har man ofte brug for et script til en dør, og det er netop hvad Door-scriptet blev udviklet til.
Door-scriptet kan få et objekt til at bevæge sig, enten ved at det flytter sig et andet sted hen, eller drejer - eller begge dele.
Lav en Cube (f.eks. med navnet "Door"), og find en passende texture - jeg bruger en texture fra "Tutorial 010" her.
Du kan f.eks. sætte transform scale på din Cube til X = 2, Y = 2.5, Z = 0.1
. Lav nogle mure ved siden af døren, så den ikke bare står ude midt i banen.
I project-panelet kan du nu finde scritpet Assets -> NighthawkFPSTemplates -> Scripts -> Door, og tilføje det til din dør.
Der er en del forskellige indstillinger på døren, men lad os starte med at se på Target Position, som angiver hvor døren skal flytte sig hen, når man åbner den.
Prøv at sætte Target Position til f.eks. X = -1.8, Y = 0, Z = 0
, og kør spillet. Gå hen til døren, kig på den, og tryk på E for at åbne den (eller lukke den igen).
Hvis du vil bruge en anden knap end E til at interagere med døre m.m. kan du ændre Interaction Key på din GameManager.
Prøv at bruge forskellige værdier for Target Position og Speed - så ser du hurtigt hvad de gør. Prøv også at slå Close Automatically til, så lukker døren automatisk. Hvor længe der går før døren lukker, kan du sætte i Auto Close Delay (i sekunder) - men bemærk at den ikke lukker før du går lidt væk fra den.
Hvis du vælger Use Auto Open vil døren automatisk åbne når du kommer tæt på, og hvis du ikke har krydset Use Interaction Key af, kan du ikke åbne døren med E. Du kan også ændre hvor tæt du skal være på døren for at åbne eller lukke den, ved både af sætte Custom Interaction Distance og sørge for at Use Default Interaction Distance ikke er krydset af.
Prøv at lege lidt med indstillingerne - du kan f.eks. også prøve at lave en elevator ved at sætte Y
-værdien i Target Position,
eller bruge Door-scriptet til at lave en platform, der kan bevæge sig.
En svingende dør
En almindelig dør drejer, når den åbner. Dette kan vi også gøre med Door-scriptet, men det bliver en anelse mere kompliceret.
Start med at lave en dør ligesom ovenfor, ud fra en Cube med scale X = 2, Y = 2.5, Z = 0.1
.
I Unity peger y
-aksen opad, så døren skal dreje 90° omkring y
-aksen for at åbne.
Dette gøres ved at sætte Delta Rotation på Door-scriptet til X = 0, Y = 90, Z = 0
, i stedet for at bruge Target Position.
Du har nu en dør, der drejer når den åbner! Men måske var det alligevel ikke helt det ønskede resultat:
Døren drejer rigtigt nok om y
-aksen, men en lokal y
-akse som ligger inde midt i døren.
For at få døren til at dreje rigtigt, som om den har hængsler i siden, skal vi have ændret rotationsaksen (altså flyttet den akse, som døren drejer omkring).
Dette kan vi ikke gøre ved at ændre på indstillingerne i Door-scriptet, men ved at bruge et lille trick med et ekstra GameObject.
Lav et tomt objekt i scenen (højre-klik i scene-hierarkiet og vælg Create Empty) og kald det "Swingdoor". Tag nu objektet med selve døren (din Cube med texture og Door-script), og flyt det ned under Swingdoor i scene-hierarkiet (som et under-objekt til Swingdoor).
Fjern Door-scriptet fra dit Cube-objekt, og put i stedet Door-scriptet på Swingdoor.
Nu skal du ændre positionen på selve døren (Cube-objekt). Den position du sætter her, bestemmer hvor rotationsaksen er (altså hvilket punkt døren drejer omkring).
Start med at sætte dørens position til 0 (X = 0, Y = 0, Z = 0
). Nu er aksen i midten af døren, men vi vil flytte aksen ud til kanten af døren.
Da vi har sat X
-scale på døren til 2
, skal X
-positionen sættes til 1
eller -1
for at flytte rotationsaksen ud til en af kanterne af døren.
Lad os derfor sætte positionen til X = -1, Y = 0, Z = 0
.
Nu hvor du har ændret positionen står døren nok ikke længere i din døråbning. For at få den tilbage på plads, skal du nu kun flytte Swingdoor-objektet, så selve døren (dit Cube-objekt) stadig har samme lokale position:
Nøgler og låste døre
På Door-scriptet kan du krydse Is Locked af, og vælge én ud af 8 nøgler som Door Key. Spilleren skal finde den tilsvarende nøgle for at åbne døren, og når først en nøgle - lad os sige "Key 1" - er fundet af spilleren, kan alle låste døre med Door Key sat til "Key 1" åbnes.
Du kan bruge Key-scriptet på et objekt, for at lægge en nøgle i banen, som spilleren kan samle op. Du kan sætte Type på Key-scriptet til f.eks. "Key 1", hvis nøglen skal åbne alle døre, der er låst med "Key 1".
Det er GameManager (GameController-scriptet) der holder styr på hvilke nøgler spilleren har fundet: GameManager har 8 checkbokse under navnet Has Key, som bliver krydset af, efterhånden som spilleren samler en ny nøgle op ("element 0" under Has Key svarer til "Key 1", "element 1" til "Key 2", osv.). Du kan krydse nøgler af i GameManager inden du starter spillet, hvis du vil have dem fra start - dette kan være nyttigt mens du udvikler/tester spillet.
Når du samler en nøgle op, får du en besked øverst på skærmen, om hvilken nøgle du har samlet op. Du kan vælge navnet på nøglerne i GameManager under Key Names, hvor "element 0" igen er "Key 1", "element 1" er "Key 2", osv.
Trigger-scriptet: Et væld af muligheder
Som sagt tidligere kan Door-scriptet bruges til meget mere end bare en dør, men det er i samspil med Trigger-scriptet at der virkelig er mulighed for at slippe fantasien løs!
Indtil videre har åbnet døre ved at gå hen til dem, og enten har de åbnet automatisk eller du har trykket E. I stedet kan du bruge en Trigger til at åbne eller lukke en dør.
Lad os bruge Trigger-scriptet til at lave et håndtag, der kan åbne en dør. Til selve håndtaget bruger vi bare en cylinder (højre-klik i scene-hierarkiet og vælg 3D Object -> Cylinder), og tilføj Trigger-scriptet til objektet med cylinderen.
På et objekt med Door-scriptet kan du nu trække cylinder-objektet (med Trigger-scriptet) ud på dørens Door Trigger. Prøv nu at start spillet, gå hen til cylinderen og trykke E - så skulle døren gerne åbne!
På Door-scriptet kan du vælge, om en Trigger kan åbne døren (Trigger Can Open) og lukke døren (Trigger Can Close). Hvis du hverken har krydset Use Interaction Key eller Use Auto Open af på Door-scriptet, kan døren kun åbnes med en Trigger.
På selve Trigger-scriptet kan du også vælge Use Interaction Key og Use Auto Open. Bemærk at du f.eks. kan lave en usynlig Trigger med Use Auto Open til at udløse fælder i din bane - det kan f.eks. være et Door-script på en plade i loftet, som flytter sig, så en stor sten kan falde ned i hovedet på spilleren! Du kan f.eks. bruge et tomt GameObject til en usynlig Trigger.
En vigtig feature ved Trigger-scriptet er, at det kan aktivere mange Door-scripts på én gang! Hvis du har flere døre i banen kan du sagtens bruge samme Trigger på dem alle.
Lad os prøve at bruge Door-scriptet på selve håndtaget (cylinder-objektet, som også har Trigger-scriptet):
Sæt cylinderens X
-rotation til 30°, og lav følgende ændringer i værdierne på cylinderens Door-script:
- Delta Rotation:
X = -60, Y = 0, Z = 0
- Speed:
4
- Close Automatically: Ja
- Auto Close Delay:
0.2
- Use Interaction Key Nej
- Custom Interaction Distance:
0
- Use Default Interaction Distance: Nej
- Door Trigger: Træk cylinderen selv herhen
- Trigger Can Close: Nej
Prøv at bruge håndtaget nu! Grunden til at vi bruger Custom Interaction Distance er for at få håndtaget til at gå tilbage på plads med det samme, selvom vi stadig står helt tæt på.
Du har måske bemærket at cylinderen drejer omkring midten af cylinderen - her kan du enten bruge samme trick med et ekstra GameObject som den svingende dør overfor. Eller måske bare lave cylinderen dobbelt så lang, og gemme halvdelen af den under gulvet i din bane.
Dobbeltdøre
Med Trigger-scriptet kan du også lave dobbeltdøre, altså to døre der åbner og lukker samtidig:
Her er det vigtigt at bruge Trigger, og at slå Use Interaction Key og Use Auto Open fra på begge døre, for ellers kan du ikke garantere, at de altid åbner og lukker sammen. Men hvad så hvis du bare vil åbne dem ved at trykke E henne ved dem, eller lade dem åbne automatisk? Så skal du stadig bruge en Trigger!
Du kan lave en usynlig Trigger midt i dobbeltdøren: Højreklik i scene-hierarkiet og vælg Create Empty, kald det tomme objekt "DoorTrigger", og tilføj Trigger-scriptet til det. Flyt nu DoorTrigger-objektet så det er placeret midt i døren, og sørg for at sætte Door Trigger på Door-scriptet af dobbeltdørene til denne nye Trigger.
Det kan nogle gange være svært at placere et tomt objekt i scenen, så i stedet for Create Empty kunne du også f.eks. lave en Cube til din DoorTrigger. Når du så har placeret den midt i døren, skal du bare slå Box Collider- og Mesh Renderer-komponenterne fra på din Cube-DoorTrigger, for at den bliver usynlig og ikke blokerer vejen for spilleren.
Nu hvor du kan lave dobbeltdøre, kan du også lave døre, der består af mange flere dele - f.eks. til en sci-fi-dør, der består af flere paneler, som glider til højre og venstre, op eller ned! Her er et eksempel:
Døren her består af tre paneler, som bevæger sig til venstre (øverst og nederst) og højre (midterste panel), og et usynligt objekt med et Trigger-script styrer døren.
Activator-scriptet
Det kan nogle gange være nyttigt at slå GameObjects til eller fra mens spillet kører, og det er netop hvad Activator gør. Og ligesom det ofte er tilfældet med Door-scriptet, skal der bruges en Trigger - faktisk fungerer Activator udelukkende sammen med Trigger-scriptet.
For at prøve Activator-scriptet af, kan du tilføje det til cylinder-objektet (håndtaget) som allerede har Trigger-scriptet. Træk cylinder-objektet over på Activator Trigger i Activator-komponenten.
Prøv at krydse både Trigger Can Activate og Trigger Can Deactivate af, og træk et objekt fra scenen over på Target - f.eks. en mur. Hvis du har krydset Trigger Can Deactivate af på din Activator skulle din Trigger (håndtaget) nu kunne få muren til at forsvinde!
Prøv også at krydse Deactivate Automatically og Activate Automatically af og se hvordan de virker (du kan også prøve at ændre Auto Activate/Deactivate Delay).
Activator-scriptet kan være nyttigt til mange ting, f.eks.:
- En kontakt der tænder/slukket lyset i et rum (Target sat til et objekt i scenen med et eller flere lys).
- Aktivering af en fælde (f.eks. Trap-scriptet, som vi ikke ser på i denne artikel).
- Visning af UI-elementer, f.eks. et panel der fortæller spilleren at man har vundet/klaret sig gennem banen.
- Ændring af selve banens layout og indhold - deaktivér et objekt i scenen med mure, gulv, loft, mm., og aktivér samtidig et andet objekt med andre mure, osv.
Et sidste eksempel, der bør fremhæves - og selve grunden til at Activator-scriptet i første omgang blev udviklet - er muligheden for at gemme en nøgle (eller andet) i en kiste. Kisten har et låg med et Door-script, som gør at spilleren kan åbne kisten. Nede i kisten ligger en nøgle med Key-scriptet. Problemet her er bare, at når spilleren går hen til kisten og trykker E for at åbne den, vil spilleren samtidig samle nøglen op, og når derfor slet ikke at se den ligge nede i kisten.
Løsningen er, at nøglen er deaktiveret fra start, og man åbner kistens låg (Door-script) med en Trigger. Den samme Trigger bliver så også brugt til at aktivere nøglen med Activator-scriptet.
Første gang med trykker E til kisten vil den åbne pga. Trigger- og Door-scripts, men nøglen bliver ikke samlet op idet den er deaktiveret. Næste gang spilleren så trykker E vil nøglen blive samlet op, idet den er blevet aktiveret af Activator-scriptet.
Andre scripts
Der er en række andre template scripts: du kan f.eks. bruge RotateMe-scriptet til at få et objekt til at dreje rundt, og scriptet Pushable er en "template-udgave" af Kasse-scriptet fra forrige artikel.
Scripts i UI-mappen er alle sammen brugt på det UI-prefab, som blev brugt under opsætningen i starten af denne artikel.
De sidste template-scripts er bl.a. beregnet til at lave våben og modstandere, og de bliver beskrevet i de næste artikler.