Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Game Art Effects

So erzeugen Sie schockierend gute 2D-Blitzeffekte in Unity (C#)

by
Read Time:33 minsLanguages:

German (Deutsch) translation by Tatsiana Bochkareva (you can also view the original English article)

Es gibt viele Einsatzmöglichkeiten für Blitzeffekte in Spielen, von der Hintergrundatmosphäre während eines Sturms bis hin zu den verheerenden Blitzangriffen eines Zauberers. In diesem Tutorial erkläre ich, wie Sie programmgesteuert fantastische 2D-Blitzeffekte erzeugen: Schrauben, Zweige und sogar Text.

Dieses Tutorial wurde speziell für Unity geschrieben, mit allen Codeausschnitten in C#. Das gleiche Tutorial ist auch mit JavaScript-Code verfügbar. Wenn Sie Unity nicht verwenden, sehen Sie sich diese plattformunabhängige Version desselben Tutorials an. Es wurde für XNA geschrieben, aber Sie sollten in der Lage sein, dieselben Techniken und Konzepte in jeder Gamedev-Engine und -Plattform zu verwenden.

Demo

Sehen Sie sich die Demo unten an:

Klicken Sie auf das Unity-Objekt und verwenden Sie dann die Zifferntasten, um zwischen den Demos zu wechseln. Bei einigen Demos müssen Sie auf eine oder zwei Stellen klicken, um sie zu aktivieren.

Grundeinstellung

Um zu beginnen, müssen Sie ein neues 2D-Projekt in Unity erstellen. Benennen Sie es, wie Sie möchten. Erstellen Sie in Unity vier Ordner: Materials, Prefabs, Skripts und Sprites.

Klicken Sie anschließend auf die Hauptkamera und stellen Sie sicher, dass die Projektion auf Orthographic eingestellt ist. Stellen Sie die Größe der Kamera auf 10 ein.

Klicken Sie mit der rechten Maustaste auf den Ordner Materials und wählen Sie Erstellen > Material. Benennen Sie es in Additive um. Wählen Sie dieses Material aus und ändern Sie seinen Shader in Partikel > Additiv. Dies wird später dazu beitragen, dass Ihr Blitz "knallt".

Schritt 1: Zeichnen Sie eine leuchtende Linie

Der Grundbaustein, aus dem wir Blitze machen müssen, ist ein Liniensegment. Öffnen Sie zunächst Ihre bevorzugte Bildbearbeitungssoftware und zeichnen Sie eine gerade Blitzlinie mit Glüheffekt. So sieht meiner aus:

Wir möchten Linien unterschiedlicher Länge zeichnen, also schneiden wir das Liniensegment wie unten gezeigt in drei Teile (schneiden Sie Ihr Bild nach Bedarf zu). Dies ermöglicht es uns, das mittlere Segment auf jede gewünschte Länge zu dehnen. Da wir das mittlere Segment strecken werden, können wir es als nur ein einzelnes Pixel dick speichern. Da das linke und das rechte Stück Spiegelbilder voneinander sind, müssen wir nur eines davon speichern; Wir können es im Code umdrehen.

Ziehen Sie Ihre Bilddateien in den Sprites-Ordner im Projektfenster. Dadurch werden die Bilddateien in das Unity-Projekt importiert. Klicken Sie auf die Sprites, um sie im Inspektorfenster anzuzeigen. Stellen Sie sicher, dass der Texturtyp auf Sprite (2D \ uGUI) eingestellt ist, und stellen Sie das Pack-Tag auf Line ein.

Das Packing Tag hilft Unity beim Zeichnen unseres Blitzes beim Zeichnen von Draw-Aufrufen zu sparen. Stellen Sie also sicher, dass Sie beiden Sprites das gleiche Packing Tag geben, sonst wird die Leistung nicht verbessert.

Jetzt deklarieren wir eine neue Klasse für das Zeichnen von Liniensegmenten:

A und B sind die Endpunkte der Linie. Durch Skalieren und Drehen der Teile der Linie können wir eine Linie beliebiger Dicke, Länge und Ausrichtung zeichnen.

Fügen Sie die folgende Draw()-Methode am Ende der Line-Klasse hinzu:

 

Die Art und Weise, wie wir das mittlere Segment und die Kappen positionieren, werden sie beim Zeichnen nahtlos verbinden. Die Startkappe wird an Punkt A positioniert, das mittlere Segment wird auf die gewünschte Breite gestreckt und die Endkappe wird um 180° gedreht und an Punkt B gezeichnet.

Jetzt müssen wir ein Prefab erstellen, mit dem unsere Line-Klasse arbeiten kann. Wählen Sie in Unity im Menü GameObject > Create Empty. Das Objekt wird in Ihrem Hierarchiebereich angezeigt. Benennen Sie es in Line um und ziehen Sie Ihr Line-Skript darauf. Es sollte in etwa wie das Bild unten aussehen.

Wir verwenden dieses Objekt als Container für die Teile unseres Liniensegments.

Jetzt müssen wir Objekte für die Teile unseres Liniensegments erstellen. Erstellen Sie drei Sprites, indem Sie GameObject > Create Other > Sprite aus dem Menü auswählen. Benennen Sie sie in StartCap, MiddleSegment und EndCap um. Ziehen Sie sie auf unser Line-Objekt, sodass sie zu seinen Kindern werden – dies sollte ungefähr wie in der Abbildung unten aussehen.

Gehen Sie jedes Kind durch und stellen Sie sein Material im Sprite-Renderer auf das zuvor erstellte Additiv-Material ein. Weisen Sie jedem Kind das entsprechende Sprite zu. (Die beiden Caps sollten das Cap-Sprite erhalten und das mittlere Segment sollte das Line-Sprite erhalten.)

Klicken Sie auf das Linienobjekt, damit Sie das Skript im Inspektorfenster sehen können. Weisen Sie den Kindern die entsprechenden Slots zu und ziehen Sie dann das Line-Objekt in den Prefabs-Ordner, um ein Prefab dafür zu erstellen. Sie können jetzt das Linienobjekt aus dem Hierarchiebedienfeld löschen.

Schritt 2: Erstellen Sie gezackte Linien

Blitze neigen dazu, gezackte Linien zu bilden, daher benötigen wir einen Algorithmus, um diese zu generieren. Wir werden dies tun, indem wir zufällig Punkte entlang einer Linie auswählen und sie um einen zufälligen Abstand von der Linie verschieben.

Die Verwendung einer völlig zufälligen Verschiebung führt dazu, dass die Linie zu gezackt wird. Daher glätten wir die Ergebnisse, indem wir einschränken, wie weit benachbarte Punkte voneinander verschoben werden können – siehe den Unterschied zwischen der zweiten und dritten Linie in der Abbildung unten.

Wir glätten die Linie, indem wir Punkte mit einem ähnlichen Versatz zum vorherigen Punkt platzieren; Dadurch kann die Linie als Ganzes auf und ab wandern und gleichzeitig verhindern, dass ein Teil davon zu gezackt wird.

Lassen Sie uns eine LightningBolt-Klasse erstellen, um das Erstellen unserer gezackten Linien zu verarbeiten.

Der Code sieht vielleicht etwas einschüchternd aus, ist aber nicht so schlimm, wenn Sie die Logik verstanden haben. Bevor wir fortfahren, sollten Sie verstehen, dass wir uns entschieden haben, unsere Liniensegmente in den Bolzen zu bündeln (da das ständige Instanziieren und Zerstören von Objekten in Unity kostspielig sein kann).

  • Die Funktion Initialize() wird einmal für jeden Blitz aufgerufen und bestimmt, wie viele Liniensegmente jeder Blitz verwenden darf.
  • Die Funktion activateLine() aktiviert ein Liniensegment mit den gegebenen Positionsdaten.
  • Die Funktion DeactivateSegments() deaktiviert alle aktiven Liniensegmente in unserer Schraube.
  • Die Funktion ActivateBolt() übernimmt die Erstellung unserer gezackten Linien und ruft die Funktion activateLine() auf, um unsere Liniensegmente an den entsprechenden Positionen zu aktivieren.

Um unsere gezackten Linien zu erstellen, berechnen wir zunächst die Steigung zwischen unseren beiden Punkten sowie den Normalenvektor zu dieser Steigung. Wir wählen dann eine Reihe von zufälligen Positionen entlang der Linie und speichern sie in unserer Positionsliste. Wir skalieren diese Positionen zwischen 0 und 1, sodass 0 den Anfang der Linie und 1 den Endpunkt darstellt. Dann sortieren wir diese Positionen, damit wir einfach Liniensegmente dazwischen einfügen können.

Die Schleife durchläuft die zufällig ausgewählten Punkte und verschiebt sie um einen zufälligen Betrag entlang der Normalen. Der Skalierungsfaktor ist dazu da, zu scharfe Winkel zu vermeiden, und die envelope stellt sicher, dass der Blitz tatsächlich zum Zielpunkt geht, indem sie die Verschiebung begrenzt, wenn wir uns dem Ende nähern. Die spread soll dabei helfen, zu kontrollieren, wie weit die Segmente von der Steigung unserer Linie abweichen; ein spread von 0 ergibt im Wesentlichen eine gerade Linie.

Also, wie wir es mit unserer Line-Klasse gemacht haben, machen wir daraus ein Fertighaus. Wählen Sie im Menü GameObject > Leer erstellen. Das Objekt wird in Ihrem Hierarchiebereich angezeigt. Benennen Sie es in Bolt um und ziehen Sie eine Kopie des LightningBolt-Skripts darauf. Klicken Sie abschließend auf das Bolt-Objekt und weisen Sie das Line-Prefab aus dem Prefabs-Ordner dem entsprechenden Slot im LightningBolt-Skript zu. Wenn Sie damit fertig sind, ziehen Sie einfach das Bolt-Objekt in den Prefabs-Ordner, um ein Prefab zu erstellen.

Schritt 3: Animation hinzufügen

Blitze sollten hell aufblitzen und dann ausblenden. Dafür sind unsere Funktionen Update() und Draw() in LightningBolt gedacht. Durch Aufrufen von Update() wird die Schraube ausgeblendet. Der Aufruf von Draw() aktualisiert die Farbe der Schraube auf dem Bildschirm. IsComplete zeigt Ihnen an, wenn der Bolzen vollständig ausgeblendet ist.

Schritt 4: Erstellen Sie eine Schraube

Nun, da wir unsere LightningBolt-Klasse haben, wollen wir sie tatsächlich sinnvoll nutzen und eine schnelle Demo-Szene einrichten.

Wir werden für diese Demo einen Objektpool verwenden, also möchten wir ein leeres Objekt erstellen, um unsere aktiven und inaktiven Schrauben aufzunehmen (einfach aus organisatorischen Gründen). Wählen Sie in Unity im Menü GameObject > Create Empty. Das Objekt wird in Ihrem Hierarchiefenster angezeigt. Benennen Sie es in LightningPoolHolder um.

Klicken Sie mit der rechten Maustaste auf den Ordner Skripte und wählen Sie Erstellen > C# Skript. Benennen Sie Ihr Skript DemoScript und öffnen Sie es. Hier ist ein kurzer Code, um Ihnen den Einstieg zu erleichtern:

Dieser Code bietet uns lediglich die Möglichkeit, Schrauben mithilfe von Objektpooling zu erstellen. Es gibt andere Möglichkeiten, dies einzurichten, aber hiermit gehen wir vor! Sobald wir es eingerichtet haben, müssen Sie nur noch zweimal klicken, um eine Schraube auf dem Bildschirm zu erstellen: einmal für die Startposition und einmal für die Endposition.

Wir benötigen ein Objekt, um unser DemoScript anzulegen. Wählen Sie im Menü GameObject > Leer erstellen. Das Objekt wird in Ihrem Hierarchiebereich angezeigt. Benennen Sie es in DemoScript um und ziehen Sie Ihr DemoScript-Skript darauf. Klicken Sie auf das DemoScript-Objekt, damit wir es im Inspektorfenster anzeigen können. Weisen Sie das Bolt Prefab aus dem Prefabs-Ordner dem passenden Slot im DemoScript zu.

Das sollte reichen, um dich in Schwung zu bringen! Führen Sie die Szene in Unity aus und probieren Sie es aus!

Schritt 5: Branch Lightning erstellen

Sie können die LightningBolt-Klasse als Baustein verwenden, um interessantere Blitzeffekte zu erstellen. Sie können die Schrauben beispielsweise wie unten gezeigt verzweigen:

Um den Blitz zu verzweigen, wählen wir zufällige Punkte entlang des Blitzes und fügen neue Bolzen hinzu, die von diesen Punkten abzweigen. Im folgenden Code erstellen wir zwischen drei und sechs Zweige, die sich in einem Winkel von 30° vom Hauptbolzen trennen.

Dieser Code funktioniert sehr ähnlich wie unsere LightningBolt-Klasse, mit der Ausnahme, dass er kein Objektpooling verwendet. Der Aufruf von Initialize() ist alles, was Sie tun müssen, um einen Verzweigungsbolzen zu erstellen; Danach müssen Sie nur noch Update() und Draw() aufrufen. Wie das geht, zeige ich Ihnen in unserem DemoScript später im Tutorial.

Möglicherweise haben Sie den Verweis auf eine GetPoint()-Funktion in der LightningBolt-Klasse bemerkt. Wir haben diese Funktion noch nicht wirklich implementiert, also kümmern wir uns jetzt darum.

Fügen Sie die folgende Funktion am Ende der LightningBolt-Klasse hinzu:

Schritt 6: Blitztext erstellen

Unten ist ein Video eines anderen Effekts, den Sie aus den Blitzen machen können:

Dafür müssen wir noch etwas mehr einrichten. Wählen Sie zunächst im Projektfenster Erstellen > RenderTexture aus. Benennen Sie es in RenderText um und setzen Sie seine Größe auf 256x256px. (Es muss nicht unbedingt genau so groß sein, aber je kleiner es ist, desto schneller wird das Programm ausgeführt.)

Wählen Sie im Menü Bearbeiten > Projekteinstellungen > Tags und Ebenen. Erweitern Sie dann im Informationsfenster das Dropdown-Menü Ebenen und fügen Sie Text in Benutzerebene 8 hinzu.

Wir müssen dann eine zweite Kamera erstellen. Wählen Sie im Menü GameObject > Andere erstellen > Kamera. Benennen Sie es in TextCamera um und stellen Sie seine Projektion auf Orthographic und seine Clear Flags auf Solid Color. Stellen Sie die Hintergrundfarbe auf (R: 0, G: 0, B: 0, A: 0) und die Culling-Maske auf nur Text (die Ebene, die wir gerade erstellt haben). Setzen Sie schließlich die Zieltextur auf RenderText (die zuvor erstellte RenderTexture). Wahrscheinlich müssen Sie später mit der Größe der Kamera herumspielen, damit alles auf den Bildschirm passt.

Jetzt müssen wir den eigentlichen Text erstellen, den wir mit unserem Blitz zeichnen werden. Wählen Sie im Menü GameObject > Andere erstellen > GUI-Text. Wählen Sie das GUI-Textobjekt aus dem Hierarchiebedienfeld aus und stellen Sie seinen Text auf LIGHTNING, seinen Anker auf die middle center und seine Ausrichtung auf die center ein. Setzen Sie dann seine Ebene auf die Textebene, die wir zuvor erstellt haben. Sie müssen wahrscheinlich mit der Schriftgröße herumspielen, damit der Text auf den Bildschirm passt.

Wählen Sie nun die Hauptkamera aus und stellen Sie ihre Culling-Maske so ein, dass sie alles außer unserer Textebene ist. Dies führt dazu, dass unser GUI-Text scheinbar vom Bildschirm verschwindet, aber er sollte auf der zuvor erstellten RenderTexture gezeichnet werden: Wählen Sie RenderText aus dem Projektfenster und Sie sollten das Wort LIGHTNING in der Vorschau unten im Fenster sehen können.

Wenn Sie das Wort LIGHTNING nicht sehen können, müssen Sie mit Ihrer Position, Schriftgröße und (Text-) Kameragröße herumspielen. Um Ihnen bei der Positionierung Ihres Textes zu helfen, klicken Sie im Hierarchie-Bedienfeld auf TextCamera und setzen Sie die Zieltextur auf None. Sie können Ihren GUI-Text jetzt sehen, wenn Sie ihn auf der TextCamera zentrieren. Sobald Sie alles positioniert haben, setzen Sie die Zieltextur der TextCamera wieder auf RenderText.

Nun zum Code! Wir müssen die Pixel aus dem Text abrufen, den wir zeichnen. Wir können dies tun, indem wir unseren Text auf ein RenderTarget zeichnen und die Pixeldaten mit Texture2D.ReadPixels() in ein Texture2D zurücklesen. Dann können wir die Koordinaten der Pixel aus dem Text als List<Vector2> speichern.

Hier ist der Code, um das zu tun:

Hinweis: Wir müssen diese Funktion beim Start unseres Programms als Coroutine ausführen, damit sie korrekt ausgeführt wird.

Danach können wir in jedem Frame zufällig Paare dieser Punkte auswählen und einen Blitz zwischen ihnen erstellen. Wir wollen es so gestalten, dass je näher zwei Punkte beieinander liegen, desto größer ist die Chance, dass wir einen Bolzen zwischen ihnen erzeugen.

Es gibt eine einfache Technik, die wir verwenden können, um dies zu erreichen: Wir wählen den ersten Punkt nach dem Zufallsprinzip aus, und dann wählen wir eine feste Anzahl anderer Punkte nach dem Zufallsprinzip und wählen den nächsten.

Hier ist der Code dafür (wir werden ihn später zu unserem DemoScript hinzufügen):

Die Anzahl der getesteten Kandidatenpunkte beeinflusst das Aussehen des Blitztextes. Wenn wir eine größere Anzahl von Punkten überprüfen, können wir sehr nahe Punkte finden, zwischen denen Bolzen gezogen werden können, wodurch der Text sehr sauber und lesbar wird, jedoch mit weniger langen Blitzen zwischen den Buchstaben. Kleinere Zahlen lassen den Blitztext wilder aussehen, aber weniger lesbar.

Schritt 7: Probieren Sie andere Variationen aus

Wir haben darüber gesprochen, Zweigblitze und Blitztexte zu erstellen, aber dies sind sicherlich nicht die einzigen Effekte, die Sie erzielen können. Schauen wir uns ein paar andere Variationen von Blitzen an, die Sie möglicherweise verwenden möchten.

Beweglicher Blitz

Vielleicht möchten Sie oft einen beweglichen Blitz machen. Sie können dies tun, indem Sie jedem Rahmen eine neue kurze Schraube am Endpunkt der Schraube des vorherigen Rahmens hinzufügen.

Burst Lightning

Diese Variante bietet einen dramatischen Effekt, der Blitze in einem Kreis aus dem Mittelpunkt schießt:

Schritt 8: Fügen Sie alles in DemoScript zusammen

Sie möchten all diese ausgefallenen Effekte, die wir bisher erstellt haben, ausprobieren können, also fügen wir sie alle in das DemoScript ein, das wir zuvor erstellt haben. Sie können zwischen den Effekten wechseln, indem Sie die Zifferntasten auf Ihrer Tastatur drücken, um den Effekt auszuwählen, und dann einfach zweimal klicken, wie wir es mit unseren Schrauben zuvor getan haben.

Hier ist der vollständige Code:

Abschluss

Blitz ist ein großartiger Spezialeffekt, um Ihre Spiele aufzuwerten. Die in diesem Tutorial beschriebenen Effekte sind ein guter Ausgangspunkt, aber es ist sicherlich nicht alles, was Sie mit Blitzen tun können. Mit etwas Fantasie können Sie alle Arten von beeindruckenden Blitzeffekten erstellen! Laden Sie den Quellcode herunter und experimentieren Sie selbst.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.