De camera is een van de belangrijkste elementen in een 3D-game. Het fungeert als de ogen van de speler, waardoor ze de spelwereld vanuit verschillende gezichtspunten kunnen zien. In Unity3D werkt een 3D-camera net als een filmcamera. Het kan worden gepanned, gekanteld en ingezoomd om scènes te plotten. In deze zelfstudie leer je hoe je meerdere perspectieven van de derde persoon camera kunt maken.
Ter inspiratie, of om een startpunt voor je eigen werk te gebruiken, bekijk je enkele van de populairste 3D-modellen op Envato Market. Of krijg een persoonlijke hulp door een van de 3D-ontwerp- en modelleringsservices te kiezen voor Envato Studio.
We hebben een eenvoudig project nodig om onze camerascripts te testen. We hebben een scène nodig met een grondvlak dat een textuur heeft. Dit maakt het gemakkelijk om te zien hoe elke camera beweegt en reageert op speler-ingangen. Als we klaar zijn, ziet het er als volgt uit:
Volg deze stappen om het project in te stellen:
Alle camera's die we gaan maken, hebben een doelwit nodig: iets om naar te kijken of te volgen. Laten we dus een basisspeler maken die we kunnen verplaatsen met de pijltjestoetsen.
Voeg in het Player-script twee openbare eigenschappen toe voor de bewegings- en draaisnelheid. Voeg vervolgens de volgende code toe aan uw Update () -methode:
openbare klasse Player: MonoBehaviour public float movementSpeed = 10; openbare float draaienSpeed = 60; void Update () float horizontal = Input.GetAxis ("Horizontal") * turningSpeed * Time.deltaTime; transform.Rotate (0, horizontaal, 0); float vertical = Input.GetAxis ("Vertical") * movementSpeed * Time.deltaTime; transform.Vertalen (0, 0, verticaal);
Dit geeft de besturing van de speler gelijk aan die van een tank. De horizontale as (de links-of-rechts-toetsen) draait de speler rond, terwijl de verticale as (omhoog of omlaag) de speler vooruit en achteruit beweegt.
Dit is de eenvoudigste camera voor de 3e persoon. Het zit op een vaste locatie in de 3D-wereld en volgt zijn doelwit als een torentje.
Maak in het LookAtCamera-script een openbaar attribuut voor het doel van onze camera bovenaan in de klas. Publieke kenmerken worden zichtbaar in de Inspector en stellen ons in staat om de speler toe te wijzen als het doel van de camera:
public class LookAtCamera: MonoBehaviour public GameObject target;
Vervolgens moeten we de transformatie van onze camera vertellen om naar het doelobject te kijken. Gelukkig hebben transform-objecten een handige LookAt () -methode die we kunnen gebruiken om precies dat te doen. We kunnen dit doen in de methode Update (), maar in plaats daarvan maken we een methode LateUpdate (). Als vuistregel moet u altijd LateUpdate () gebruiken in plaats van de methode Update () in alle camerascripts. LateUpdate () gebeurt nadat Update () is voltooid, dus het Player-script heeft een kans om de positie van de speler te berekenen voordat de camera de positie berekent. Dit resulteert in een soepelere camerabeweging:
void LateUpdate () transform.LookAt (target.transform);
Het uiteindelijke script moet er als volgt uitzien:
public class LookAtCamera: MonoBehaviour public GameObject target; void LateUpdate () transform.LookAt (target.transform);
Als u het spel nu probeert uit te voeren, krijgt u fouten die klagen over UnassignedReferenceException. Om dit te voorkomen, sleept u de speler vanuit het hiërarchische paneel en zet u hem neer op de eigenschap Target van het script in het infovenster. De camera heeft nu een geldig doel om naar te kijken.
Dit is het type camera dat je normaal gesproken zou vinden in games als Diablo, ook wel een "dungeon crawler" -game genoemd. De camera zit boven de speler en beweegt ten opzichte van het personage, maar draait nooit.
In het script DungeonCamera moeten we opnieuw een openbaar attribuut maken voor het doel van onze camera. We moeten ook een variabele maken om de offset tussen de camera en zijn doel op te slaan. De offset wordt weergegeven als een Vector3 en wordt gebruikt om de relatieve afstand te behouden terwijl de speler zich verplaatst. U zult misschien opmerken dat we de waarde niet een waarde geven wanneer we deze voor het eerst declareren. Dit komt omdat we de waarde berekenen wanneer het script de eerste keer wordt uitgevoerd. We kunnen de Start () -methode gebruiken om dit te doen:
public class DungeonCamera: MonoBehaviour public GameObject target; Vector3 offset; void Start () offset = transform.position - target.transform.position;
In elk frame moeten we de positie van de camera bijwerken op basis van de positie van de speler door de offset toe te passen. Zoals gewoonlijk moet dit worden gedaan in de methode LateUpdate ():
void LateUpdate () Vector3 desiredPosition = target.transform.position + offset; tranform.position = desiredPosition;
Sleep de speler van het paneel Hiërarchie naar de eigenschap Target van het script in het infovenster.
Je merkt misschien dat de camerabeweging een beetje stijf is. Het zou leuk zijn om de beweging enigszins te dempen, zodat het enige tijd kost om de speler in te halen. We kunnen dit doen met de Vector3.Lerp () -methode. Lerp interpoleert lineair tussen twee punten, wat betekent dat het vloeiend overgaat van het ene punt naar het andere in een rechte lijn.
Om te bepalen hoeveel demping wordt toegepast, kunnen we een ander openbaar attribuut creëren met de naam: demping!
openbare vlotter-demping = 1;
De twee punten waar we tussen kunnen werken zijn de huidige positie van de camera met toegepaste demping en de gewenste positie zonder demping.
void LateUpdate () Vector3 desiredPosition = target.transform.position + offset; Vector3 positie = Vector3.Lerp (transform.position, desiredPosition, Time.deltaTime * demping); transform.position = positie;
Ten slotte willen we dat de camera blijft kijken naar de speler:
transform.LookAt (target.transform.position);
Het definitieve script ziet er als volgt uit:
public class DungeonCamera: MonoBehaviour public GameObject target; openbare vlotter-demping = 1; Vector3 offset; void Start () offset = transform.position - target.transform.position; void LateUpdate () Vector3 desiredPosition = target.transform.position + offset; Vector3 positie = Vector3.Lerp (transform.position, desiredPosition, Time.deltaTime * demping); transform.position = positie; transform.LookAt (target.transform.position);
Dit type camera wordt veel gebruikt in platformgames zoals Mario Galaxy. De camera zit achter en boven de speler en draait rond het personage terwijl ze draaien.
Net als de Dungeon Crawler-camera heeft de Follow-camera een publiek attribuut nodig voor zowel een doel als een offset. De offset moet worden ingesteld in de methode Start ():
public class FollowCamera: MonoBehaviour public GameObject-doel; Vector3 offset; void Start () offset = target.transform.position - transform.position;
Om de camera achter het doel te oriënteren, moeten we eerst de hoek van het doel bepalen en er een rotatie van maken in de methode LateUpdate ():
void LateUpdate () float desiredAngle = target.transform.eulerAngles.y; Quaternion rotatie = Quaternion.Euler (0, desiredAngle, 0);
We kunnen dan de offset vermenigvuldigen met de rotatie om de offset op dezelfde manier te richten als het doel. Vervolgens trekken we het resultaat af van de positie van het doelwit.
transform.position = target.transform.position - (rotatie * offset);
Om naar de speler te blijven kijken:
transform.LookAt (target.transform);
Sleep de speler van het paneel Hiërarchie naar de eigenschap Target van het script in het infovenster.
Dezelfde dempingsbeweging die we hebben toegepast op de Dungeon-camera kan worden toegepast op de Follow-camera. Eerst voegen we een dempingsattribuut toe om het dempen eenvoudiger te maken:
openbare vlotter-demping = 1;
In plaats van te ploeteren tussen twee punten zoals we deden met de Dungeon-camera, plooien we tussen de hoek van de camera en de hoek van het doel. Dus, in plaats van Vector3.Lerp (), gebruiken we de Mathf.LerpAngle () -methode. We vervangen de oorspronkelijke hoekcode door:
vlotterstroomAngle = transform.eulerAngles.y; float desiredAngle = target.transform.eulerAngles.y; zweefstand = Mathf.LerpAngle (currentAngle, desired Angle, Time.deltaTime * demping); Quaternion rotation = Quaternion.Euler (0, angle, 0);
Het uiteindelijke script moet er als volgt uitzien:
public class FollowCamera: MonoBehaviour public GameObject-doel; openbare vlotter-demping = 1; Vector3 offset; void Start () offset = target.transform.position - transform.position; void LateUpdate () float currentAngle = transform.eulerAngles.y; float desiredAngle = target.transform.eulerAngles.y; zweefstand = Mathf.LerpAngle (currentAngle, desired Angle, Time.deltaTime * demping); Quaternion rotation = Quaternion.Euler (0, angle, 0); transform.position = target.transform.position - (rotatie * offset); transform.LookAt (target.transform);
Dit type camera is vergelijkbaar met de Follow-camera, behalve dat de rotatie wordt bestuurd door de muis, die vervolgens het personage wijst in de richting waarin de camera kijkt.
Net als de Follow-camera heeft de muis-doelcamera een publiek attribuut nodig voor een doel en rotatiesnelheid, evenals een offset. De offset moet worden ingesteld in de methode Start ():
openbare klasse MouseAimCamera: MonoBehaviour public GameObject-doel; openbare float rotateSpeed = 5; Vector3 offset; void Start () offset = target.transform.position - transform.position;
We hebben toegang tot de horizontale as van de muis (ook bekend als: Mouse X) en gebruiken deze om het doelwit te draaien.
float horizontaal = Input.GetAxis ("Mouse X") * rotateSpeed; target.transform.Rotate (0, horizontaal, 0);
Vervolgens oriënteren we de offset in dezelfde richting en trekken deze van de positie van het doel af om de camera achter het doel te houden.
float desiredAngle = target.transform.eulerAngles.y; Quaternion rotatie = Quaternion.Euler (0, desiredAngle, 0); transform.position = target.transform.position - (rotatie * offset); transform.LookAt (target.transform);
Sleep de speler van het paneel Hiërarchie naar de eigenschap Target van het script in het infovenster.
In tegenstelling tot de andere scripts, voegen we geen enkele demping toe aan de beweging van de camera. Vanwege de precieze aard van de muis kan dit vaak leiden tot bewegingsziekte.
Het definitieve script zou er als volgt uit moeten zien:
openbare klasse MouseAimCamera: MonoBehaviour public GameObject-doel; openbare float rotateSpeed = 5; Vector3 offset; void Start () offset = target.transform.position - transform.position; void LateUpdate () float horizontal = Input.GetAxis ("Mouse X") * rotateSpeed; target.transform.Rotate (0, horizontaal, 0); float desiredAngle = target.transform.eulerAngles.y; Quaternion rotatie = Quaternion.Euler (0, desiredAngle, 0); transform.position = target.transform.position - (rotatie * offset); transform.LookAt (target.transform);
Meer dan één camerascript kan tegelijkertijd op een enkele camera worden toegepast. Als u wilt schakelen tussen de verschillende scripts, schakelt u het gewenste script in door het aan te vinken en alle andere scripts uit te vinken. Dit kan handig zijn om over te schakelen naar een andere camerastijl voor het maken van opnamen of het knippen van scènes.
Unity wordt ook geleverd met verschillende camerascripts die u direct uit de verpakking kunt gebruiken. De scripts zijn goed gedocumenteerd, eenvoudig aan te passen en maken geweldige handleidingen voor het bouwen en verbeteren van uw eigen camerascripts.
Unity maakt het eenvoudig om een grote verscheidenheid aan camera's voor elk type spel te bouwen. Met slechts een paar regels code is het belangrijkste element in je game klaar voor gebruik. Hoewel sommigen misschien een beetje intimiderend vinden, biedt Unity zoveel handige gemaksfuncties dat de meeste zware berekeningen al voor je zijn gedaan.
Klik hier om het complete Unity-project te downloaden.