Die Kamera ist eines der wichtigsten Elemente in einem 3D-Spiel. Es fungiert als Augen des Spielers und lässt die Spielwelt aus verschiedenen Blickwinkeln sehen. In Unity3D funktioniert eine 3D-Kamera wie eine Filmkamera. Es kann auf Bildszenen geschwenkt, geneigt und vergrößert werden. In diesem Lernprogramm erfahren Sie, wie Sie mehrere Kameraperspektiven für Dritte erstellen.
Sehen Sie sich einige der beliebtesten 3D-Modelle auf dem Envato Market an, um Inspiration zu erhalten oder um einen Ausgangspunkt für Ihre eigene Arbeit zu verwenden. Oder holen Sie sich individuelle Hilfe, indem Sie einen der 3D-Design- und Modellierungsservices von Envato Studio auswählen.
Wir benötigen ein einfaches Projekt, um unsere Kameraskripte zu testen. Wir benötigen eine Szene mit einer Grundebene, die eine Textur aufweist. So können Sie leicht sehen, wie sich jede Kamera auf die Eingaben des Players bewegt und wie sie reagieren. Wenn wir fertig sind, sollte es so aussehen:
Führen Sie die folgenden Schritte aus, um das Projekt einzurichten:
Alle Kameras, die wir erstellen werden, benötigen ein Ziel: etwas zum Anschauen oder Folgen. Lassen Sie uns also einen Basisspieler erstellen, den wir mit den Pfeiltasten bewegen können.
Fügen Sie im Player-Skript zwei öffentliche Eigenschaften für die Bewegung und die Drehgeschwindigkeit hinzu. Fügen Sie der Update () -Methode dann den folgenden Code hinzu:
public class Spieler: MonoBehaviour public float movementSpeed = 10; public float drehenSpeed = 60; void Update () float horizontal = Input.GetAxis ("Horizontal") * Wendegeschwindigkeit * Time.deltaTime; transform.Rotate (0, horizontal, 0); float vertical = Input.GetAxis ("Vertical") * movementSpeed * Time.deltaTime; transform.Translate (0, 0, vertikal);
Dadurch erhält der Spieler ähnliche Bedienelemente wie ein Panzer. Die horizontale Achse (die linke oder rechte Taste) dreht den Spieler um, während die vertikale Achse (Auf- oder Abwärts-Tasten) den Spieler vorwärts und rückwärts bewegt.
Dies ist die einfachste 3rd-Person-Kamera. Es sitzt an einem festen Ort in der 3D-Welt und verfolgt sein Ziel wie ein Turm.
Erstellen Sie im Skript LookAtCamera ein öffentliches Attribut für das Ziel unserer Kamera an der Spitze der Klasse. Die öffentlichen Attribute werden im Inspector angezeigt und ermöglichen es, den Player als Ziel der Kamera festzulegen:
public class LookAtCamera: MonoBehaviour öffentliches GameObject-Ziel;
Als Nächstes müssen wir der Transformation unserer Kamera mitteilen, dass sie das Zielobjekt betrachten soll. Zum Glück haben Transformationsobjekte eine praktische LookAt () - Methode, mit der wir genau das tun können. Wir könnten dies in der Update () -Methode tun, stattdessen erstellen wir eine LateUpdate () -Methode. Als Daumenregel sollten Sie in allen Kamerascripts immer LateUpdate () anstelle der Update () -Methode verwenden. LateUpdate () findet statt, nachdem Update () abgeschlossen ist. Das Player-Skript hat also die Möglichkeit, die Position des Spielers zu berechnen, bevor die Kamera ihre Position berechnet. Dies führt zu einer ruhigeren Kamerabewegung:
void LateUpdate () transform.LookAt (target.transform);
Das letzte Skript sollte folgendermaßen aussehen:
public class LookAtCamera: MonoBehaviour öffentliches GameObject-Ziel; void LateUpdate () transform.LookAt (target.transform);
Wenn Sie versuchen, das Spiel jetzt auszuführen, erhalten Sie Fehler, die sich über UnassignedReferenceException beschweren. Um dies zu verhindern, ziehen Sie den Player aus dem Hierarchiebedienfeld und legen Sie ihn im Inspector in der Eigenschaft Target des Skripts ab. Die Kamera hat jetzt ein gültiges Ziel zum Anschauen.
Dies ist der Kameratyp, den Sie normalerweise in Spielen wie Diablo finden, auch bekannt als "Dungeon-Crawler" -Spiel. Die Kamera sitzt über dem Player und bewegt sich relativ zum Charakter, dreht sich jedoch nie.
Im DungeonCamera-Skript müssen wir erneut ein öffentliches Attribut für das Ziel unserer Kamera erstellen. Wir müssen auch eine Variable erstellen, um den Versatz zwischen der Kamera und ihrem Ziel zu speichern. Der Versatz wird als Vector3 dargestellt und wird verwendet, um die relative Entfernung beizubehalten, während sich der Spieler bewegt. Sie stellen möglicherweise fest, dass wir dem Offset keinen Wert zuweisen, wenn wir ihn zum ersten Mal angeben. Dies liegt daran, dass der Wert bei der ersten Ausführung des Skripts berechnet wird. Wir können dazu die Start () -Methode verwenden:
öffentliche Klasse DungeonCamera: MonoBehaviour öffentliches GameObject-Ziel; Vektor3 Versatz; void Start () offset = transform.position - target.transform.position;
In jedem Frame müssen wir die Position der Kamera basierend auf der Position des Spielers durch Anwenden des Versatzes aktualisieren. Wie üblich sollte dies in der LateUpdate () -Methode erfolgen:
void LateUpdate () Vector3 desirePosition = target.transform.position + offset; tranform.position = gewünschte Position;
Ziehen Sie den Player aus dem Hierarchiebedienfeld auf die Target-Eigenschaft des Skripts im Inspektor.
Sie stellen möglicherweise fest, dass die Kamerabewegung etwas steif ist. Es wäre schön, die Bewegung etwas zu dämpfen, so dass es einige Zeit dauert, den Spieler einzuholen. Wir können dies mit der Vector3.Lerp () -Methode tun. Lerp interpoliert linear zwischen zwei Punkten, was bedeutet, dass es in einer geraden Linie glatt von einem Punkt zum anderen übergeht.
Um zu steuern, wie viel Dämpfung angewendet wird, können Sie ein anderes öffentliches Attribut erstellen, das als Dämpfung bezeichnet wird!
öffentliche Schwimmdämpfung = 1;
Die zwei Punkte, zwischen denen wir liegen können, sind die aktuelle Position der Kamera mit angewendeter Dämpfung und die gewünschte Position ohne Dämpfung.
void LateUpdate () Vector3 desirePosition = target.transform.position + offset; Vector3 Position = Vector3.Lerp (Transformationsposition, gewünschte Position, ZeitdeltaTime * Dämpfung); transform.position = position;
Schließlich möchten wir, dass die Kamera den Player immer wieder betrachtet:
transform.LookAt (target.transform.position);
Das letzte Skript sieht so aus:
öffentliche Klasse DungeonCamera: MonoBehaviour öffentliches GameObject-Ziel; öffentliche Schwimmdämpfung = 1; Vektor3 Versatz; void Start () offset = transform.position - target.transform.position; void LateUpdate () Vector3 desiredPosition = target.transform.position + offset; Vector3 Position = Vector3.Lerp (Transformationsposition, gewünschte Position, ZeitdeltaTime * Dämpfung); transform.position = position; transform.LookAt (target.transform.position);
Dieser Kameratyp wird häufig in Plattformspielen wie Mario Galaxy eingesetzt. Die Kamera sitzt hinter und über dem Player und dreht sich beim Drehen um den Charakter.
Wie die Dungeon Crawler-Kamera benötigt die Follow-Kamera ein öffentliches Attribut sowie ein Offset. Der Versatz sollte in der Start () -Methode festgelegt werden:
öffentliche Klasse FollowCamera: MonoBehaviour öffentliches GameObject-Ziel; Vektor3 Versatz; void Start () offset = target.transform.position - transform.position;
Um die Kamera hinter dem Ziel auszurichten, müssen wir zunächst den Winkel des Ziels ermitteln und es in der LateUpdate () -Methode in eine Drehung umwandeln:
void LateUpdate () float desiredAngle = target.transform.eulerAngles.y; Quaternion Rotation = Quaternion.Euler (0, erwünschterAngle, 0);
Wir können dann den Versatz mit der Drehung multiplizieren, um den Versatz genauso wie das Ziel auszurichten. Wir ziehen dann das Ergebnis von der Position des Ziels ab.
transform.position = target.transform.position - (Rotation * Offset);
Um den Spieler weiter anzuschauen:
transform.LookAt (target.transform);
Ziehen Sie den Player aus dem Hierarchiebedienfeld auf die Target-Eigenschaft des Skripts im Inspektor.
Dieselbe Dämpfungsbewegung, die wir auf die Dungeon-Kamera angewendet haben, kann auf die Follow-Kamera angewendet werden. Zuerst fügen wir ein Dämpfungsattribut hinzu, um die Einstellung der Dämpfung zu erleichtern:
öffentliche Schwimmdämpfung = 1;
Anstatt zwischen zwei Punkten zu verfahren, wie wir es bei der Dungeon-Kamera getan haben, bewegen wir uns zwischen dem Kamerawinkel und dem Winkel des Ziels. Anstelle von Vector3.Lerp () verwenden wir also die Mathf.LerpAngle () -Methode. Wir ersetzen den ursprünglichen Winkelcode durch:
float currentAngle = transform.eulerAngles.y; float desireAngle = target.transform.eulerAngles.y; Schwimmwinkel = Mathf.LerpAngle (currentAngle, erwünschterAngle, Time.deltaTime * Dämpfung); Quaternion-Drehung = Quaternion.Euler (0, Winkel, 0);
Das letzte Skript sollte folgendermaßen aussehen:
öffentliche Klasse FollowCamera: MonoBehaviour öffentliches GameObject-Ziel; öffentliche Schwimmdämpfung = 1; Vektor3 Versatz; void Start () offset = target.transform.position - transform.position; void LateUpdate () float currentAngle = transform.eulerAngles.y; float desireAngle = target.transform.eulerAngles.y; Schwimmwinkel = Mathf.LerpAngle (currentAngle, erwünschterAngle, Time.deltaTime * Dämpfung); Quaternion-Drehung = Quaternion.Euler (0, Winkel, 0); transform.position = target.transform.position - (Rotation * Offset); transform.LookAt (target.transform);
Dieser Kameratyp ähnelt der Follow-Kamera, mit der Ausnahme, dass die Drehung von der Maus gesteuert wird, die dann den Charakter in die Richtung zeigt, in die die Kamera zeigt.
Wie die Follow-Kamera benötigt die Mouse Aim-Kamera ein öffentliches Attribut für Ziel und Rotationsgeschwindigkeit sowie einen Versatz. Der Versatz sollte in der Start () -Methode festgelegt werden:
public class MouseAimCamera: MonoBehaviour öffentliches GameObject-Ziel; öffentlicher Schwimmer rotateSpeed = 5; Vektor3 Versatz; void Start () offset = target.transform.position - transform.position;
Wir können auf die horizontale Achse der Maus zugreifen (auch bekannt als Maus X) und damit das Ziel drehen.
Float horizontal = Input.GetAxis ("Mouse X") * Rotationsgeschwindigkeit; target.transform.Rotate (0, horizontal, 0);
Dann richten wir den Versatz in dieselbe Richtung aus und ziehen ihn von der Position des Ziels ab, um die Kamera hinter dem Ziel zu halten.
float desireAngle = target.transform.eulerAngles.y; Quaternion Rotation = Quaternion.Euler (0, erwünschterAngle, 0); transform.position = target.transform.position - (Rotation * Offset); transform.LookAt (target.transform);
Ziehen Sie den Player aus dem Hierarchiebedienfeld auf die Target-Eigenschaft des Skripts im Inspektor.
Im Gegensatz zu den anderen Skripten werden wir die Kamerabewegung nicht dämpfen. Aufgrund der genauen Beschaffenheit der Maus kann es oft zu Bewegungskrankheiten kommen.
Das letzte Skript sollte so aussehen:
public class MouseAimCamera: MonoBehaviour öffentliches GameObject-Ziel; öffentlicher Schwimmer rotateSpeed = 5; Vektor3 Versatz; void Start () offset = target.transform.position - transform.position; void LateUpdate () float horizontal = Input.GetAxis ("Mouse X") * rotateSpeed; target.transform.Rotate (0, horizontal, 0); float desireAngle = target.transform.eulerAngles.y; Quaternion Rotation = Quaternion.Euler (0, erwünschterAngle, 0); transform.position = target.transform.position - (Rotation * Offset); transform.LookAt (target.transform);
Es kann mehr als ein Kameraskript gleichzeitig auf eine einzelne Kamera angewendet werden. Um zwischen den verschiedenen Skripts zu wechseln, aktivieren Sie das gewünschte Skript, indem Sie es markieren und alle anderen deaktivieren. Dies kann nützlich sein, wenn Sie zu einem anderen Kamerastil wechseln möchten, um Aufnahmen zu erstellen oder Szenen zu schneiden.
Unity wird auch mit mehreren Kamerascripts geliefert, die Sie sofort verwenden können. Die Skripts sind gut dokumentiert, leicht anpassbar und bieten großartige Anleitungen zum Erstellen und Verbessern eigener Kamerascripts.
Unity macht es einfach, eine Vielzahl von Kameras für jede Art von Spiel zu erstellen. Mit nur wenigen Zeilen Code ist das wichtigste Element in Ihrem Spiel einsatzbereit. Während einige die Mathematik ein wenig einschüchternd finden, bietet Unity so viele nützliche Komfortfunktionen, dass die meisten Berechnungen bereits für Sie erledigt sind.
Klicken Sie hier, um das gesamte Unity-Projekt herunterzuladen.