Flipbook-Textur: So animieren Sie Sprites in Unity, Godot und VRChat
Erstellen Sie Ihre eigene Flipbook-Textur
Eine Flipbook-Textur spielt ein Sprite-Sheet Frame für Frame auf einer einzigen Fläche ab. Erfahren Sie, wie Sie eine in Unity, Godot und VRChat erstellen und ein echtes Sprite-Sheet live in 3D durchblättern.
Eine Flipbook-Textur ist ein Sprite-Sheet, das ein Shader Frame für Frame auf einer einzigen Fläche abspielt. Es gibt kein Rig und keine Timeline: Das Sheet enthält jeden Frame in einem festen Raster, und das Material bewegt ein kleines Fenster mit konstanter Geschwindigkeit über dieses Raster. Ein 8 x 8 Sheet enthält 64 Frames; bei 12 Frames pro Sekunde läuft es in etwa 5.3 Sekunden durch. Das Mesh ändert sich nie, keine Textur wird neu hochgeladen, und die gesamte Animation kostet einen einzigen Textur-Lookup.
Diese Seite behandelt die vier Zahlen, die ein Flipbook-Shader benötigt, und wie der Frame-Index auf UV-Koordinaten abgebildet wird, die zwei Möglichkeiten, eine Flipbook-Textur in Unity anzusteuern, wie ein Poiyomi-Flipbook auf einem VRChat-Avatar eingerichtet wird, das Äquivalent in Godot und Phaser und wie Sie Ihr eigenes Sheet aus einem GIF oder aus einer schriftlichen Beschreibung erstellen.
Kurze Antwort
Eine Flipbook-Textur ist ein Sprite-Sheet, das als Shader-Animation verwendet wird und über die Zeit nach Zeile und Spalte indexiert wird. Das Sheet liegt in einem Textur-Slot; jede Shader-Auswertung berechnet einen Frame-Index aus verstrichener Zeit und einer Framerate, reduziert diesen Index auf eine Spalte und eine Zeile und bildet die UVs der Fläche auf diese einzelne Zelle ab. Frame = floor(time * fps) mod frameCount, column = frame mod columns, row = floor(frame / columns). Ein 6 x 6 Sheet mit 10 FPS durchläuft 36 Frames in 3.6 Sekunden, vollständig auf der GPU, ohne Upload pro Frame und ohne Änderung des Draw Calls.
So funktioniert eine Flipbook-Textur
Vier Zahlen definieren die Animation. Spalten und Zeilen beschreiben das Layout des Sheets. Die Frame-Anzahl ist normalerweise Columns mal Rows, und bei diesem Wert läuft der Index um. Die Framerate bestimmt, wie schnell der Index voranschreitet. Alles andere — Filtering, Wrap-Modus, UV-Insets — dient dazu, den Sampler davon abzuhalten, außerhalb der aktuellen Zelle zu lesen.
Die Index-Mathematik ist kurz und es lohnt sich, sie auszuschreiben. Gegeben sei die verstrichene Zeit t: frame = floor(t * fps) mod frameCount, column = frame mod columns, row = floor(frame / columns). Das UV-Fenster ist dann tiling = (1 / columns, 1 / rows) und offset = (column / columns, row / rows). Die vertikale Richtung ist der Teil, der viele aus der Bahn wirft. Die meisten Sheet-Authoring-Tools schreiben Zeile 0 an den oberen Rand des Bildes, während die UV-Ursprünge von Unity und Godot unten links liegen. Bei einem Sheet mit oberster Zeile zuerst wird in Unity offset.y zu 1 - (row + 1) / rows; andernfalls laufen die Zeilen invertiert ab und der erste Frame der Animation ist die letzte Zeile des Sheets.
Die Filterung entscheidet, ob das Ergebnis sauber ist. Stellen Sie den Wrap-Modus des Sheets auf Clamp. Bei Repeat liest eine Abtastung am rechten Rand der Textur den linken Rand, sodass eine Pixelspalte aus Frame 0 im letzten Frame jeder Zeile auftaucht. Schalten Sie Mipmaps für hartkantige Pixelart aus, denn die Mip-Kette mittelt benachbarte Zellen und die Animation wird zu Brei, sobald die Fläche einige Meter entfernt ist. Wenn die Ziel-Engine oder der Shader Mipmaps erzwingt, lassen Sie einen ein oder zwei Pixel breiten transparenten Rand um jede Zelle, oder ziehen Sie das UV-Fenster um ein halbes Texel an allen vier Seiten ein.
| Wert | Was er steuert |
|---|---|
| Columns | Frames nebeneinander. Legt das horizontale Tiling einer Zelle fest: 1 / columns. |
| Rows | Rows im Sheet. Legt das vertikale Tiling fest: 1 / rows. Für einen Strip 1 verwenden. |
| Frame count | Insgesamt indexierte Frames, normalerweise columns x rows. Hier läuft der Index um. |
| FPS | Wie schnell der Index voranschreitet. floor(time * fps) ergibt den aktuellen Frame. |
| Wrap mode | Clamp. Repeat lässt den Sampler über den Sheet-Rand hinweg lesen. |
| Filter mode | Point, mit ausgeschalteten Mipmaps, oder UVs um ein halbes Texel pro Zelle einziehen. |
Flipbook-Textur in Unity
Es gibt zwei Wege, und sie schlagen auf unterschiedliche Weise fehl. Weg eins ist ein Shader, der den Zeilen- und Spaltenindex selbst besitzt und sich selbst animiert. Weg zwei ist das Animation-Fenster, das Tiling und Offset des Materials mit Keyframes versieht, während ein einfacher Lit- oder Unlit-Shader das Sampling übernimmt. Weg eins ist besser für Effekte, die mit der Spielzeit synchron bleiben müssen; Weg zwei ist besser, wenn die Animation von einem Animator-State gesteuert und in der Timeline zusammen mit allem anderen in der Szene sichtbar sein soll.
Legen Sie in jedem Fall zuerst den Import des Sprite-Sheets fest: Wrap Mode Clamp, Mip Maps aus, Filter Mode Point und keine Kompression bei Pixelart. Diese drei Einstellungen verursachen mehr Flipbook-Fehler als die Shader-Mathematik.
Weg 1: ein Shader mit Zeilen- und Spaltenindex
In Shader Graph nimmt der Flipbook-Node Columns, Rows und einen zeitgesteuerten Frame-Index entgegen und gibt die neu abgebildeten UVs aus. In einem handgeschriebenen Shader legen Sie _Columns, _Rows und _Fps als Properties offen und berechnen die Zelle in der Vertex- oder Fragment-Stufe. Wenn die Animation über Objekte hinweg synchron sein muss, steuern Sie den Frame-Index über einen Script-Float an, statt _Time.y in jedem Material unabhängig abzutasten, damit zwei Flipbooks auf demselben Objekt nicht auseinanderdriften können.
Weg 2: Das Animation-Fenster steuert Tiling und Offset
Dieser Weg animiert den _ST-Vektor der Textur. Built-in Standard und Unlit verwenden _MainTex_ST; URP Lit und Unlit verwenden _BaseMap_ST. Das Tiling bleibt fest bei (1, 1 / rows) und nur offset.y ändert sich. Die folgenden Schritte gelten für diesen Weg.
01
Wählen Sie das Material aus und öffnen Sie das Animation-Fenster. Erstellen Sie einen Clip und fügen Sie dann die _ST-Vektor-Property der Textur als Track hinzu — sie erscheint als Vector4 am Material.
02
Setzen Sie die Sample Rate des Clips auf denselben Wert wie Ihre Ziel-FPS. Wenn die Sample Rate niedriger ist als die gewünschten FPS, fallen Keyframes auf denselben Sample zusammen und die Animation läuft langsamer als beabsichtigt.
03
Setzen Sie offset.y einmal pro Frame als Key: value = 1 - (row + 1) / rows für ein Sheet mit oberster Zeile zuerst, tiling = (1, 1 / rows).
04
Stellen Sie die Interpolation jedes Keyframes im Kurveneditor auf Constant. Linear blendet zwei Zellen ineinander und Sie sehen beide Frames gleichzeitig als Ghosting.
05
Stellen Sie sicher, dass der letzte Key nicht den Wert des ersten Frames wiederholt, sonst hält die Animation am Loop-Übergang einen Frame lang an.
06
Wenn mehrere Renderer dasselbe Material verwenden, animieren Sie pro Renderer einen MaterialPropertyBlock, statt renderer.material zu lesen, was das Material beim ersten Zugriff klont und die Kopie für die Lebensdauer des Objekts am Leben lässt.
Poiyomi-Flipbook für VRChat
Der Flipbook-Bereich des Poiyomi-Shaders scrollt ein UV-Fenster über ein Sheet direkt am Material, sodass ein Material-Slot einen animierten Sprite auf einem Avatar-Mesh anzeigen kann. Er bietet Rows, Columns und eine Framerate sowie einen Modus, in dem Sie den Frame-Index selbst steuern, statt ihn von der Shader-Zeit ablaufen zu lassen.
Verwenden Sie einen einzeiligen Strip statt eines Rasters. Ein Strip gibt dem Shader eine einzige Achse, entlang der er schreitet, was die vertikale Naht vollständig beseitigt. Bei einem Raster muss sich das UV-Fenster am Ende jeder Zeile eine Zeile nach unten bewegen, und jede Filterung, Mip-Stufe oder Halb-Texel-Rundungsfehler an dieser Grenze tastet die benachbarte Zeile ab — sichtbar als dünnes Band eines anderen Frames während der Wiedergabe. Ein Strip macht den Frame-Index außerdem zu einer direkten Multiplikation: Die Frame-Breite in UV ist 1 / frameCount, und der Offset ist einfach frame / frameCount. Bei einer 8-Frame-Animation aus 256 x 256-Zellen ist der Strip 2048 x 256 und bleibt eine Zweierpotenz.
Alpha ist auf einem Avatar wichtiger als in einer flachen Szene. Wenn der Sprite harte Kanten hat, verwenden Sie Cutout oder Opaque. Flipbooks in der Transparent-Queue schreiben keine Tiefe, und auf einem Avatar sortieren sie sich gegen den Körper und gegeneinander auf eine Weise, die sich mit dem Kamerawinkel ändert. Behalten Sie die animierte Fläche wenn möglich auf einem Material, das bereits auf dem Avatar liegt — jeder zusätzliche Material-Slot zählt gegen den Performance-Rang Ihres Avatars. Wenn der Frame-Index von einem Animator-State mit einem synchronisierten Parameter gesteuert wird, sieht jeder Client denselben Frame; ein aus der Shader-Zeit berechneter Frame-Index wird lokal ausgewertet und kann bei verschiedenen Betrachtern an einer anderen Stelle in der Schleife stehen.
01
Exportieren Sie die Frames als einen horizontalen Strip. Die Strip-Höhe entspricht der Zellenhöhe; die Strip-Breite entspricht Frame-Anzahl mal Zellenbreite. Lassen Sie am Ende keine leere Zelle übrig.
02
Importieren Sie die Textur mit Wrap Mode Clamp, Mip Maps aus und sRGB an. Aktivieren Sie Alpha Is Transparency nur, wenn der Strip tatsächlich Alpha enthält.
03
Erstellen Sie ein Poiyomi-Material, weisen Sie es dem animierten Mesh zu und öffnen Sie den Flipbook-Bereich.
04
Setzen Sie Rows auf 1 und Columns auf die Frame-Anzahl. Stellen Sie die Framerate passend zur gewünschten Dauer ein — 8 Frames bei 8 FPS ergeben eine Schleife von einer Sekunde.
05
Wählen Sie die Frame-Quelle. Der manuelle Modus stellt einen Frame-Index bereit, den Sie von einem Animator-State aus steuern; der zeitgesteuerte Modus läuft von selbst in einer Schleife.
06
Stellen Sie unter Rendering für hartkantige Sprites Cutout oder Opaque ein. Lassen Sie Transparent nur für weichkantige Effekte und rechnen Sie mit Eigenheiten beim Depth-Sorting.
07
Prüfen Sie die Schleife: Der letzte Frame darf keine Kopie des ersten sein, sonst friert der Sprite bei jedem Durchlauf einen Frame lang ein.
08
Testen Sie mit einem hochgeladenen Avatar und einem Spiegel, aus der Nähe und von der anderen Seite der Instanz. Bei Entfernung treten Mip- und Filterprobleme auf.
Flipbook in Godot und Phaser
In Godot 4 ist der 2D-Weg AnimatedSprite2D mit einer SpriteFrames-Ressource. Importieren Sie das Sheet, öffnen Sie SpriteFrames, setzen Sie Hframes und Vframes auf die Spalten- und Zeilenanzahl, fügen Sie die Frames für die Animation hinzu, stellen Sie dann die Geschwindigkeit der Animation in Frames pro Sekunde ein und lassen Sie Loop an. SpriteFrames speichert die Animation als Liste von Frame-Indizes, sodass sowohl ein Raster-Sheet als auch ein einzelner Strip ohne UV-Mathematik auf Ihrer Seite funktionieren.
Wenn Sie nur eine Animation benötigen, ist ein einfaches Sprite2D leichter: Setzen Sie Hframes und Vframes einmal und lassen Sie dann die Integer-Property frame von einem AnimationPlayer mit Step-Interpolation voranschreiten. Tweenen Sie frame nicht mit einer Standard-Easing-Kurve — der Wert ist ein Integer-Index, und eine Interpolation rundet entweder auf einen einzelnen Wert ab oder flackert zwischen zwei Zellen.
Für ein Flipbook auf einer 3D-Fläche in Godot ist ein ShaderMaterial mit derselben Zeilen- und Spaltenmathematik wie in der Unity-Version der kürzeste Weg: uv = UV * vec2(1.0 / cols, 1.0 / rows) + vec2(col / cols, row / rows), wobei die Zeile aus dem Frame-Index berechnet wird. Der UV-Ursprung von Godot liegt unten links, genau wie bei Unity, daher benötigt ein Sheet mit oberster Zeile zuerst denselben vertikalen Flip.
In Phaser 3 wird das Sheet einmal geladen und zur Ladezeit zerlegt. frameWidth und frameHeight definieren die Zelle, Frames werden von links nach rechts und von oben nach unten nummeriert, und die Animation wird über Frame-Nummern statt über Koordinaten identifiziert — es gibt keinen Shader zu schreiben und keine Zeilen- und Spaltenarithmetik, die man falsch machen könnte.
| Engine | Objekt | Was Sie einstellen |
|---|---|---|
| Godot 4 | AnimatedSprite2D + SpriteFrames | Hframes und Vframes auf das Sheet-Layout, dann die Animationsgeschwindigkeit in FPS mit aktiviertem Loop. |
| Godot 4 | Sprite2D | Hframes und Vframes einmal, dann die Integer-Property frame, vorangeschritten durch einen AnimationPlayer mit Step-Interpolation. |
| Godot 4 | ShaderMaterial auf einem 3D-Mesh | Columns, Rows und ein Frame-Index im Shader, mit demselben UV-Remap und vertikalen Flip wie in Unity. |
| Phaser 3 | this.load.spritesheet | frameWidth und frameHeight; Phaser zerlegt das Sheet von links nach rechts, von oben nach unten. |
| Phaser 3 | this.anims.create | Frames aus anims.generateFrameNumbers, plus frameRate und repeat: -1 zum Loopen. |
Ein Sprite-Sheet live in 3D durchblättern
Die spielbare Szene in diesem Abschnitt ist The Cyclops' Island, ausgeführt im 3D-Spiel-Builder von Neta Studio. Das Flipbook auf dem Bildschirm ist dieselbe oben beschriebene Index-zu-UV-Operation, ausgewertet in einem Three.js-Shader auf der GPU — der Unterschied ist, dass sie auf einem echten Mesh in einer echten Szene läuft, mit einer Kamera, die Sie steuern, und Lichtern, die sich bewegen.
Das ist wichtiger, als es klingt. Ein Flipbook in einer flachen Unity-Szene wird normalerweise frontal betrachtet, wo Naht-Bleeding und Mip-Blending schwer zu erkennen sind. Bewegen Sie die Kamera in einem flachen Winkel um eine animierte Fläche, zeigen sich die Probleme sofort: ein Band der benachbarten Zelle am Frame-Rand, die letzte Mip-Stufe, die zwei Frames zu einem Brei mittelt, oder eine Alpha-Kante, die von vorn korrekt aussieht und von der Seite verschwindet. Die Browser-Version macht die Schleife zwischen dem Erstellen eines Sheets und dem Ansehen auf einer Fläche kurz genug, um ohne Build-Schritt zu iterieren.
Mini World ist die kleinere Szene, um ein einzelnes Sheet zu testen — eine geringere Mesh-Anzahl und eine kürzere Ladezeit. Agent Sprite Forge generiert die Frames, wenn Sie noch kein Sheet haben, und beide Szenen verwenden denselben Flipbook-Pfad, sodass ein Sheet, das in Mini World richtig aussieht, sich in The Cyclops' Island genauso verhält.
Erstellen Sie Ihr eigenes Sheet
Es gibt drei Wege zu einem nutzbaren Sheet: ein vorhandenes GIF konvertieren, ein Raster auf einen einzelnen Strip zuschneiden oder Frames aus einer schriftlichen Beschreibung generieren. Alle drei enden bei derselben Datei — eine PNG, bei der jede Zelle dieselbe Größe hat, von links nach rechts und von oben nach unten angeordnet, wobei die Sheet-Breite ein sauberes Vielfaches der Zellenbreite ist.
Ein GIF zu konvertieren ist der Weg mit der meisten versteckten Arbeit, denn ein GIF ist keine Sequenz vollständiger Frames. Frames sind häufig partielle Diffs gegenüber dem vorherigen Frame, und Verzögerungen werden pro Frame in Hundertstelsekunden gespeichert. Ein Flipbook-Shader akzeptiert nur eine Framerate, daher muss variables Timing vor dem Export in duplizierte Frames eingeebnet werden.
Ein Raster auf einen Strip zuzuschneiden ist mechanisch: Behalten Sie die benötigte Zeile, beschneiden Sie die Höhe auf eine Zelle und lassen Sie die Breite als Frame-Anzahl mal Zellenbreite. Das ist der richtige Schritt, wenn ein Raster-Sheet als einzelne Animation verwendet wird, denn es entfernt die vertikale Achse und die Naht, die damit einhergeht. Aus einer Beschreibung zu generieren ist der dritte Weg — Agent Sprite Forge nimmt eine Aktion und eine Frame-Anzahl entgegen und gibt ein Sheet mit fester Zellgröße zurück, was die manuelle Abstimmungsarbeit erspart, Frames auszurichten, die einzeln exportiert wurden.
01
Eben Sie vor dem Export jeden GIF-Frame ein. Dekodieren Sie jeden Frame auf eine Canvas, die den vorherigen Frame weiterführt, sonst exportieren Sie die Diff-Rechtecke statt des Bildes.
02
Normalisieren Sie das Timing. Wählen Sie die kürzeste oder die mediane GIF-Verzögerung und duplizieren Sie dann Frames, wo die Quelle länger hielt, damit das Sheet mit einer konstanten FPS abgespielt wird.
03
Ordnen Sie die Frames von links nach rechts, von oben nach unten an, jede Zelle identisch in der Größe. Machen Sie die Sheet-Abmessungen zu einem exakten Vielfachen der Zellgröße — ein Sheet, das 9.5 Zellen breit ist, tastet für immer die falschen Texel ab.
04
Um auf einen Strip zuzuschneiden, beschneiden Sie die Höhe auf eine Zelle und behalten die Breite bei Frame-Anzahl mal Zellenbreite. Löschen Sie die leere Endzelle, wenn das Quellraster eine hatte.
05
Fügen Sie um jede Zelle einen ein oder zwei Pixel breiten transparenten Rand hinzu, wenn die Ziel-Engine das Deaktivieren von Mipmaps nicht zulässt. Andernfalls ziehen Sie das UV-Fenster an allen vier Seiten um ein halbes Texel ein.
06
Um statt zu konvertieren zu generieren, schreiben Sie die Aktion, die Frame-Anzahl und die Blickrichtung, und lassen Sie Agent Sprite Forge ein Sheet mit fester Zellgröße zurückgeben, statt Frames einzeln zu exportieren und von Hand auszurichten.
07
Verifizieren Sie, indem Sie den Frame-Index in der Engine schrittweise einzeln durchgehen. Wenn eine Zelle am Rand einen Splitter ihres Nachbarn zeigt, sind das Sheet-Layout oder das UV-Inset falsch, nicht der Shader.
Betreten Sie die Welt, zu der es gehört
Ein Sprite ist eine Figur ohne Ort zum Stehen. Der letzte Schritt ist der, den sonst niemand anbietet: Nehmen Sie das Sheet, das Sie gerade erstellt haben, und setzen Sie es in eine Welt, in der jemand herumlaufen kann — eine kleine Insel, einen Planeten, eine regnerische Straßenecke. Jede Welt auf dieser Seite wurde aus einer schriftlichen Beschreibung erstellt und als spielbare Seite veröffentlicht.
FAQ
Was ist ein Poiyomi-Flipbook? +
Es ist der Flipbook-Bereich des Poiyomi-Shaders, der ein UV-Fenster über ein Sprite-Sheet auf einem Material scrollt, sodass ein Material-Slot einen animierten Sprite auf einem Avatar-Mesh anzeigen kann. Sie stellen Rows, Columns und eine Framerate ein und lassen den Frame-Index entweder von der Shader-Zeit ablaufen oder steuern ihn von einem Animator-State aus. Ein einzeiliger Strip wird bevorzugt, weil er die vertikale Naht zwischen den Zeilen entfernt.
Kann man ein GIF direkt als Flipbook verwenden? +
Nein. Ein GIF speichert Verzögerungen pro Frame und oft nur die Pixel, die sich geändert haben, während ein Flipbook-Shader eine Textur und eine konstante Framerate erwartet. Konvertieren Sie es zuerst: Eben Sie jeden Frame auf den vorherigen ein, normalisieren Sie das Timing und schreiben Sie das Ergebnis in ein festes Zellenraster. Der Shader sieht das GIF nie.
Warum blutet meine Flipbook-Textur zwischen Frames? +
Der Sampler liest außerhalb des aktuellen Zellenfensters. Stellen Sie den Textur-Wrap-Modus auf Clamp, schalten Sie Mipmaps für hartkantige Art aus und ziehen Sie das UV-Fenster an jeder Seite um ein halbes Texel ein. Das Bluten wird mit der Entfernung schlimmer, weil dort die Mip-Kette beginnt, benachbarte Zellen miteinander zu mitteln.
Welche Framerate sollte ein Flipbook verwenden? +
8 bis 12 FPS wirken handanimiert und eignen sich für Charakter-Sprites; 24 bis 30 eignen sich für Feuer, Wasser und andere kontinuierliche Effekte. Der Shader hat genau eine Rate, also duplizieren Sie Frames, wenn die Quelle variables Timing hatte, statt zu versuchen, die Geschwindigkeit mitten in der Schleife zu variieren.
Brauche ich ein Raster, oder reicht eine Zeile? +
Eine Zeile reicht für alles, was als Sequenz abgespielt wird, und sie entfernt eine Achse von Nahtfehlern. Raster sind für Sheets, die mehrere Animationen in einer Textur unterbringen, wobei der Shader oder die Engine eine Zeile für Idle, Run oder Attack auswählt. Wenn aus einem Raster-Sheet nur eine Animation hervorgeht, schneiden Sie es auf einen Strip zu.
Funktioniert ein Flipbook mit dem Lit-Shader von Unity URP? +
Nicht ohne Weiteres — URP Lit hat keinen Frame-Index. Verwenden Sie Shader Graph mit dem Flipbook-Node, der Columns, Rows und einen zeitgesteuerten Index entgegennimmt, oder animieren Sie Tiling und Offset von _BaseMap_ST des Materials mit konstanter Keyframe-Interpolation. Built-in Standard und Unlit verwenden _MainTex_ST unter denselben Regeln.
Zurück zum 3D Game Builder
Alle 31 fertigen 3D-Welten, Spiele und Szenen befinden sich auf einer Seite — jede einzelne spielbar.
Sprite-Asset-Bibliothek öffnen
Jedes Asset in dieser Bibliothek ist eine transparente, spielfertige PNG mit einem aufgezeichneten Prompt — Sprite-Sheet-Ressourcen und kostenlose Sprite-Sheets, getaggt nach Aktion, Stil und Motiv. Kostenlos zum Durchsuchen und Herunterladen.