Alle Beiträge

  • Die besten Quellen für 3D-Modelle

    Die besten Quellen für 3D-Modelle

    Bei der Produktion Deines Games kannst Du 3D-Modelle selbst erstellen oder einen Designer beauftragen, sofern dies der Projektrahmen ermöglicht. Als Einzelentwickler oder in kleinen Teams entstehen aber sehr leicht Engpässe, so dass Zeit, Geld oder Fähigkeiten nicht ausreichen, um alles selbst zu machen. Auf dieser Seite habe ich eine Reihe von Webseiten verlinkt, auf denen Du fertige Modelle für Dein Spiel findest.

    Welche Datei-Formate funktionieren für Unity?

    Da Unity eine GameEngine und kein Modellierungswerkzeug ist, sind speziell für Unity optimierte Modelle nur selten zu finden. Sehr viel verbreiteter sind Universalformate wie .obj, .max und .dae, die ursprünglich einer spezifischen Modellierungssoftware wie 3ds max oder Maya entstammen. Bei diesen Formaten ist nicht sicher, wieweit sich das jeweilige Modell in Unity fehlerfrei importieren lässt. Im Allgemeinen funktionieren das .fbx und .obj-Format einigermaßen zuverlässig, wobei insbesondere komplexe Inhalte wie Animationen gelegentlich Probleme bereiten.

    [kursbanner thema=“csharp“]

    Wichtig: Nutzungslizenzen beachten

    Sieh dir genau an unter welchen Lizenzbedingungen ein Modell zum Download angebotenen wird und prüfe, ob sie zu Deinem Projekt passen. Einige Modelle darfst Du zum Beispiel nur verwenden, wenn auch Dein Spiel kostenlos ist. Viele Modelle darfst Du zwar verwenden, aber Du musst die Quelle in den Credits Deines Spiels angeben. Achte auf die genauen Lizenbedingungen und verwende niemals Modelle, die ohne Nutzungsregeln angeboten werden.

    Besonders heikel sind offene Tauschbörsen bei denen keine rechtliche Prüfung stattfindet. Hier findet sich viel Fan-Art. Wird zum Beispiel ein 3D-Modell einer berühmten Spielfigur unter einer kostenlosen Lizenz angeboten, so bedeutet das nicht, dass das Modell frei verwendet werden kann, da die Figur selbst möglicherweise geschützt ist und der Autor des Modells zur Vergabe von Nutzungsrechten garnicht befähigt ist.

    Quellen für 3D-Modelle

    1. [linktipp url=“https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=popularity/query=category:0″ title=“Unity AssetStore“ pros=“für Unity,kostenlos,game-optimiert“ cons=““ tags=“unity“]Die beste Quelle für Unity-optimierte Assets. Über 20000 Modelle verfügbar, viele davon kostenlos.[/linktipp]
    2. [linktipp url=“https://itch.io/game-assets/free/tag-3d“ title=“itch.io Game Assets“ pros=“für Unity, game-optimiert, kostenlos“ cons=“Lizenzen unübersichtlich“ tags=“blender, unity“]Hier finden sich tolle kostenlose Modelle, die bereits für Spieleentwicklung optimiert sind. Die Lizenzregelungen sind teils unklar.[/linktipp]
    3. [linktipp url=“https://www.blendswap.com/“ title=“Blendswap“ pros=“kostenlos“ cons=“Viel Fanart“ tags=“blend, cc-Lizenzen“]Modelle, die sich in Blender nachbearbeiten lassen. Achtung: auch viel Fanart, für die ggf. Urheberrechtsbeschränkungen gelten![/linktipp]
    4. [linktipp url=“https://www.gamedevmarket.net/category/3d/“ title=“GameDev Market“ pros=“game-optimiert, kostenlos oder günstig“ cons=“Nachbearbeitung nötig“ tags=“obj, fbx“]Die Modelle auf dieser Seite sind zwar für Games optimiert, benötigen aber evtl. Nachbearbeitung oder Konvertierung. Neben den kostenlosen werden einige Modelle zum Kauf angeboten, allerdings zu sehr günstigen Preisen.[/linktipp]
    5. [linktipp url=“https://opengameart.org/“ title=“Open Game Art“ pros=“kostenlos, game-optimiert“ cons=“mäßige Qualität“ tags=“fbx, blender, cc-Lizenzen“]Viel Material, das für Spiele-Entwicklung optimiert ist, allerdings von sehr unterschiedlicher Qualität.[/linktipp]
    6. [linktipp url=“https://www.blender-models.com/“ title=“Blender Models“ pros=“kostenlos“ cons=“gemischte Qualität “ tags=“blender, cc-Lizenzen“]Wer sich nicht davor scheut auch noch selbst in Blender Hand anzulegen und die Modelle für Unity aufzubereiten, der findet hier viele kostenlose Modelle. [/linktipp]
    7. [linktipp url=“https://free3d.com/“ title=“Free3D“ pros=“kostenlos“ cons=““ tags=“3ds, obj, dae, blender“]Viele kostenlose Modelle in sehr unterschiedlichen Formaten. Die Nutzungslizenzen unterscheiden sich je nach Modell.[/linktipp]
    8. [linktipp url=“https://www.cgtrader.com/3d-models“ title=“CG-Trader“ pros=“Hohe Qualität“ cons=“Hohe Preise“ tags=“obj,fbx“]Tolle Modelle, hauptsächlich für Animations-Produktion interessant.[/linktipp]
    9. [linktipp url=“https://www.turbosquid.com/“ title=“Turbo Squid“ pros=“hohe Qualität“ cons=“kostenpflichtig“ tags=“fbx, blender, obj“]Großartiger Store für 3D-Modelle, allerdings kostenpflichtig und noch nicht für Games/Unity optimiert.[/linktipp]
    10. [linktipp url=“https://3docean.net/category/3d-models“ title=“3D Ocean“ pros=“gute Qualität“ cons=“kostenpflichtig“ tags=“fbx, max, obj“]Über 40000 Modelle werden bei 3D-Ocean zu sehr unterschiedlichen Preisen angeboten.[/linktipp]

    Bonus

    • [linktipp url=“https://www.yobi3d.com/“ title=“Yobi Model-Suchmaschine“ pros=“viele Ergebnisse“ cons=“keine Lizenzprüfung“ tags=““]Mit dieser Suchmaschine kannst Du nach 3D-Modellen suchen! Ein Nachteil ist, dass diese Maschine einfach alles sucht und viele Ergebnisse Lizenzeinschränkungen haben.[/linktipp]

    [bildnachweis]Beitragsbild: Auto bilder durch Kjpargeter – Freepik.com entwickelt, Website-Thumbnails erstellt durch thumbnail.ws[/bildnachweis]

  • Per Histogramm die Effizienz einer UV-Textur einschätzen

    Per Histogramm die Effizienz einer UV-Textur einschätzen

    Bei der Erstellung einer Pixel-genauen Textur für ein 3D-Modell kommt es darauf an, möglichst viel der Informationen im Bild zu nutzen und auf das 3D-Modell abzubilden. Da die Bilddatei eine feste Größe hat und somit der Speicher in jedem Fall beim Laden der Textur belegt wird, ist jeder ungenutzte Pixel im Grunde verschwendete Rechenkapazität. Zwar ist es fast nicht möglich, wirklich 100% der Textur auszunutzen, weil die Objektgeometrie in der Regel aus unregelmäßig geformten Flächen besteht, doch man kann zumindest versuchen, den Platz so weit wie möglich auszunutzen. Die Histogrammfunktion von Photoshop und Gimp enthält eine Funktion zur Pixelzählung, die wir einsetzen können, um die Verteilung von belegten und ungenutzten Pixeln zu messen.

    So stellst Du per Histogramm fest, wie viele Pixel ungenutzt sind (ungefähr)

    Um festzustellen, wie viel Fläche ungefähr ungenutzt ist, kannst Du das Histogramm in Photoshop bzw. Gimp einsetzen:

    1. Öffne die UV-Textur in Photoshop oder Gimp und lege eine neue, transparente Ebene an

    Zeichne in diese Ebene mit einer grellen Farbe die ungenutzten Flächen ein. Du kannst in Photoshop auch eine Form-Ebene verwenden, musst diese dann aber rastern, bevor Du zum nächsten Schritt gehst.

    Freie Flächen markieren
    Freie Flächen markieren

    2. Öffne das Fenster „Histogramm“

    In Photoshop: Menü Fenster > Histogramm In Gimp: Menü Farben > Information > Histogramm

    3. Wähle die Ebene aus und lies die Pixelzahl ab

    Nur in Photoshop: Wähle im Histogramm-Fenster als Quelle: Ausgewählte Ebene.

    Lies die Anzahl der Pixel Deiner Ebene im Feld „Pixel“ im Histogramm-Fenster ab. Im Beispiel unten belegen die grünen Pixel 6740 Pixel.

    Ablesen der Pixelzahl im Histogramm
    Ablesen der Pixelzahl im Histogramm

    4. Ermittle die Pixel des gesamten Bildes

    Du kannst entweder die Länge und Breite des gesamten Bildes multiplizieren, d.h. z.B. 256 × 256 = 65536 oder die Größe ebenfalls im Histogramm ablesen:

    • In Photoshop setze Quelle auf Gesamtes Bild und lies erneut Pixel ab.
    • In Gimp brauchst Du eine Ebene in der Bildgröße ohne Transparenz, um den Pixel-Wert im Histogramm ablesen zu können. Wenn Dein Texturbild keine Transparenz enthält, kannst Du dieses nehmen. Ansonsten eine neue vollfarbige Fläche hinzufügen und auswählen oder die Pixelzahl eben einfach anhand der Bildgröße ausrechnen.

    5. Teile die Anzahl der Ebenen-Pixel durch die der Gesamt-Pixel, um einen Prozentwert zu erhalten

    In meinem Beispiel hat die Ebene 6740 Pixel und das Bild insgesamt 65536 Pixel.

    6740 / 65536 = 0,10284423828125 0,10 = 10%

    In meinem Bild sind also ca. 10% Fläche ungenutzt.

    Ein ungefährer Anhaltspunkt

    Natürlich ist diese Messung nicht vollkommen exakt, zumal nicht alle leeren Pixel markiert wurden und es sowieso schwierig ist, hier hundertprozentig zwischen ungenutzt und genutzt zu unterscheiden. Vor allem entlang der Kanten zeichnet man in der Praxis meist einige Pixel größer als die eigentliche UV-Projektion ist. Damit lässt sich sicherstellen, dass die Texturfarbe das Modell immer ganz abdeckt, auch wenn es zum Beispiel durch Skalierung der Textur zu rechnerischen Überblendungen kommt.

    Es geht aber auch nicht darum, eine technisch präzise Maßangabe zu bekommen. Viel mehr soll der hier vorgestellte Ansatz helfen, relativ große Leerräume einschätzen zu können. Große leere Bereiche in der Textur lassen sich meistens durch ändern des UV-Mappings verbessern.

    [kursbanner thema=“blender“]

  • Biped-Workshop: Fast 3 Stunden neues Trainings-Material

    Biped-Workshop: Fast 3 Stunden neues Trainings-Material

    Ich freue mich sehr, heute die Veröffentlichung von fast 3 Stunden neuem Videomaterial zum Thema Biped / Charakterdesign in meinem Online-Kurs Der komplette Blender-Kurs für Unity: Lerne 3D-Modellierung anzukündigen. Das Update ist für alle früheren Teilnehmer komplett kostenlos!

    Die Erstellung virtueller Charaktere ist ein komplexes, aber wichtiges Thema in der Spiele-Entwicklung. Bisher hatte mein Kurs nur die Grundlagen abgedeckt. Im nun veröffentlichten Abschnitt „Biped Workshop“ befassen wir uns konkret mit den Herausforderungen der Umsetzung einer Figur mit menschenähnlichem Körperbau.

    Das ist im Update enthalten:

    • Skizzieren und Vorbereiten des Bauplans
    • Alle Modellierungsschritte der Figur
    • Einsatz von automatisch gespiegelter Modellierung der Körperhälften
    • Wichtige Merkmale der Anatomie, „Rule of Three“ für bewegliche Gelenke
    • Export und schnelles Auto-Rigging
    • Anwenden von realistischen Motion-Capture-Datensätzen
    • Import und Setup des Modells in Unity
    • Sequenzen mit Unity’s Timeline-Editor erstellen, Überblenden von Animationen
    • Umsetzung eines einfachen Third-Person-Scripts zur Steuerung mit den WASD-Tasten
    • Import des animierten Modells in Blender zur Nachbearbeitung
    • Programmgesteuerte Keyframe-Reduzierung zur Minimierung der Datenmenge
    • Ansatz um Inverse Kinematik in Blender einzubauen
    • Unwrapping, Texturpainting, Anwendung mehrerer Materialien für Körperpartien
    • Erstellung eines anpassbaren Charakters in Unity
      • Texturen per Skript austauschen (z.B. Kleidung)
      • dynamisches Hinzufügen/Ändern von Gegenständen (z.B. Hüte, Waffen, usw.)

    Durch Eurer Feedback verbessert – Vielen Dank!

    Ich habe bei der Erstellung der neuen Kursinhalte das Feedback bisheriger Teilnehmer umgesetzt. So spielen sehr lange Sequenzen nun im Zeitraffer ab, um das Kurstempo etwas zu erhöhen. Zudem gehe ich auf neue Funktionen in Blender und Unity ein, um noch mehr Detailwissen zu vermitteln.

    ​20 neue Videos mit ​2 Stunden 45 Minuten ​Laufzeit

    ​Sieh Dir hier eine Vorschau der neuen Themen an: 

    Starte Jetzt!

    • ​Die neuen Inhalte sind sofort kostenlos zugänglich, wenn Du den Kurs bereits gebucht hast!
    • check​Als Neukunde erhältst Du das Update + alle bisherigen Inhalte, wenn Du Dich jetzt einschreibst.

  • Wie ich einen neuartigen Grafik-Stil in Unity realisierte

    ​In meinem Adventure-Game A Room Beyond ​habe ich ​eine Kombination aus selbst erstellter Pixel-Grafik und automatisierten Bildberechnungen genutzt, um das ​Gefühl von klassischen 2D-Abenteuern mit 3D-Mitteln nachzuahmen. ​Diese​r Effekte ​weckte viel Interesse und wurde immer wieder als Innovativ und ​neuartig empfunden. ​Der folgende ​Artikel, der im Making-Games-Magazins und auf Made with Unity ​veröffentlicht​ wurde, erklärt die Verfahren und Hintergründe​.

    ​Als ich 2014 das grobpixelige 2D-Abenteuer “The Last Door” entdeckte, war ich von der dichten Atmosphäre dieser lovecraftschen Gruselgeschichte begeistert. Ich fragte mich allerdings, wieweit es möglich ist, den Sinneseindruck handgezeichneter Retro-Pixel-Abenteuer mit heutiger 3D-Rendertechnik zu vereinen. In einem kurzen Experiment baute ich einen kubistischen Character in Blender und erweiterte ihn in Unity zu einem spielbaren Prototyp. Die vielversprechenden ersten Gehversuche wuchsen schnell zu einem ganzen Point-and-Click-Adventure, dem Indie-Projekt „A Room Beyond“. Oft werde ich seither nach den technischen Details des semi-dreidimensionalen Pixel-Looks gefragt. Im Folgenden soll daher aufgezeigt werden, welche konzeptuellen, gestalterischen und technischen Schritte der „2.5D“-Pixelgrafik zugrunde liegen und warum ein einfaches Postprocessing nicht ausreicht, um sich dem Charme von nostalgischer Pixelgrafik anzunähern.

    Warum überhaupt Pixel-Rendering?

    Zu Zeiten der frühen Point’n’Click-Adventures, wie etwa den großartigen Lucas Arts-Spielen, begründete sich die charakteristische pixelige Bildgestaltung in technischen Begrenzungen der damaligen Hardware. Die meisten Hintergründe, Sprites und Animationen  wurden Bild für Bild von Hand gezeichnet, was ein charmantes handgemachtes Aussehen zur Folge hatte. Allerdings hatte diese Technik auch ihre Einschränkungen: alles Sichtbare war auf das explizit gezeichnete beschränkt. Bewegungen ließen sich beispielsweise nur in der in den Einzelbildern hinterlegten Perspektive und Bildrate darstellen. Auch Lichteffekte wie Schlaglichter oder dramaturgischer Schattenwurf waren nur durch statische Vorabproduktionen möglich.

    Ungeachtet der technischen Möglichkeiten und Grenzen kann Pixelgrafik ein attraktiver visueller Effekt sein, zumal er die Vorstellungskraft des Betrachters stimuliert. Dadurch, dass eben nicht jedes Detail sichtbar ist, sondern ein abstrahierendes Mosaik auf dem Bildschirm erscheint, bleibt Spielraum für eigene Interpretationen. Ähnlich dem Lesen eines Buchs das im Gegensatz zu seiner Verfilmung viele konkrete Details offen lässt, bereichert die eigene Vorstellung des Spielers das gesamte Spielerlebnis.

    Nachdem die heutige Rechenleistung ausreicht, um Effekte wie 3D-Bewegungen und Beleuchtungsmodelle in Echtzeit darzustellen, liegt die Idee nahe, die Schwächen der Pixelgrafik mit Echtzeiteffekten zu kompensieren. Trotz seiner Offensichtlichkeit scheinen nur wenige Projekte diesen Ansatz bisher tatsächlich zu verfolgen.

    [kursbanner thema=“kreativ“]

    ​Komponenten der Inszenierung

    Eine bloße Verringerung der Bildpunkte (Downsampling) reicht nicht aus, um sich dem Eindruck manuell gezeichneter Pixelgrafik anzunähern, zumal dieser Effekt leicht als solcher zu erkennen ist. Statt dessen kommt eine Kombination mehrerer gestalterischer Entscheidungen und technischer Mittel in „A Room Beyond“ zum Einsatz, um die visuelle Erscheinung von Pixelgrafik nachzuahmen. Abb. 1 fasst die wichtigsten Bausteine für die Gesamtkomposition zusammen.

    Abb. 1: Das finale Bild ist das Ergebnis von Postprocessing, 3D-Objekten als auch speziellen Texturen und Overlays.

    Grundsätzlicher Aufbau. Jede Kameraeinstellung basiert auf einer in Unity realisierten 3D-Szene. Boden, Wände und andere für räumliche Bewegungen relevante Elemente basieren auf niedrig aufgelösten Polygon-Meshes. Dekorationen, statische Hintergrundbilder und Vordergrund-Masken kommen als einfache texturierte Ebenen hinzu, was einerseits die Performanz erhöht und andererseits das direkte Einbinden handgezeichneter Bereiche erlaubt.

    Post-Processing. Ein Pixelierungs-Shader rastert vor dem Zeichnen der GUI-Elemente das Kamerabild. Durch geringfügige Anpassungen kann der Code des quelloffenen „unity-facesensor“ für diesen Zweck zum Einsatz kommen. Besondere Relevanz hat der Shader für die Darstellung sichtbarer Pixel entlang von 3D-Objekt-Kanten, die wiederum von der Kameraperspektive abhängen (Abb. 2).

    Abb. 2: Postprocessing-Pixelierung wirkt sich besonders stark auf die Pixel entlang von Objektkanten aus. Der Effekt ist daher vor allem dort deutlich sichtbar, wo die Mesh-Geometrie Kontraste erzeugt, etwa an den äußeren Konturen und in Schattenbereichen.

    Die nachträgliche Pixelierung des im Speicher hochaufgelösten Kamerabildes beansprucht einiges an Rechenleistung, weshalb zunächst die Vermutung nahe lag, dass ein direktes Rendering in geringer Auflösung und die anschließende Vergrößerung auf Bildschirmauflösung effizienter sein könnte. In der Tat konnte für eine entsprechende Testimplementierung eine deutliche Verbesserung der Bildrate gemessen werden. Jedoch traten auch Probleme zutage: In der Schattenberechnung erschienen inakzeptable Fehler und Artefakte, Kantenglättungsverfahren konnten  nicht (zufriedenstellend) in das Render-Ergebnis eingebunden werden. Zudem erforderten die das gepixelte Kamerabild überlagernden GUI-Elemente den Einsatz eines weiteren Renderschritts mithilfe einer zusätzlichen Kamera. Dieses doppelte Rendering relativiert dann jedoch wiederum die gegenüber dem Pixel-Shader gewonnenen Einsparungseffekte. Außerdem verändert sich bei dieser technischen Architektur die Auswertung von Maus-Eingabesignalen, was einen zusätzlichen Workaround-Code zur Nachbildung der herkömmlichen Abläufe erfordert. Da schließlich auch Einschränkungen bei Vorschau und Interaktivität dieses Verfahrens innerhalb des Unity-Editors auftraten, muss abschließend festgestellt werden, dass sich der Einsatz des teureren Pixelierungsshaders gegenüber dem direkten Rendern in niedriger Auflösung schlicht aus Gründen der Einfachheit, Flexibilität und Fehlerfreiheit bewährt hat.

    [kursbanner thema=“csharp“]

    ​Texturen

    Um die Sichtbarkeit der Pixel innerhalb von Formflächen zu erhöhen, eignen sich pixelige Texturen. Sehr niedrig aufgelöste, über die Objektoberfläche skalierte Texturen mit hohen Kontrasten liefern dabei meist gute Ergebnisse. Auch die Deaktivierung von Unitys Importoptimierungen wie Glättungsfilter und Speicheroptimierungen („2er-Potenz-Korrektur“) tragen zu scharfen Pixelkanten bei. Gestalterisch lässt sich die visuelle Plastizität von 3D-Objekten verbessern, indem Texturen entlang deren räumlichen Verlaufs platziert werden (Abb. 3).

    Abb. 3:Durch Abbilden der Textur entlang der räumlichen Richtung des 3D-Meshes verbessert sich die Plastizität des Steins.

    Die grafische Attraktivität wird zudem durch den Szenenkontext beeinflusst: Objekte sollten nicht nur isoliert betrachtet texturiert werden, sondern unter Beachtung der Umgebungselemente in der finalen Szene. Es hat sich gezeigt, dass eine ausgewogene Mischung aus rauschenden (z.B. Holzboden in Abb. 1)  und einfarbigen Texturen (z.B. Schrank in Abb. 1) häufig ein ansprechendes, comic-haftes Gesamtbild liefert.

    ​Beleuchtung

    Das Kamerakonzept in „A Room Beyond“ beruht auf statischen Blickwinkeln mit harten Schnitten. Je nach Standort der Spielfigur wählt das Spiel eine Kamera aus, um den entsprechenden Szenenabschnitt bestmöglich darzustellen. Einerseits ist diese Statik dem Einsatz des Pixel-Shaders geschuldet, der bei Kamerabewegungen aufgrund des veränderten Renderergebnisses zu starkem Flimmern aller Pixel führen würde. Andererseits ermöglicht der Einsatz statischer Kameras aber auch eine stärkere Anlehnung an aus der Filmtheorie bekannte Bildgestaltungskonzepte. Regisseure wie Alfred Hitchcock zeigen in ihren Arbeiten, wie das Prinzip des „Mise en Cadre“ als dramaturgisches Werkzeug funktioniert. Die Platzierung von Objekten innerhalb des sichtbaren Bildrahmens folgt dabei nicht einfach den momentan aktiven Darstellern, sondern richtet sich vorrangig nach dramaturgischen Fragen. So unterstützen ungewöhnliche – möglicherweise sogar bewusst unnatürliche – Kameraperspektiven und Beleuchtungsmodelle besonders dramatische Momente und Emotionen der Erzählung. Ein ikonisches Leitmotiv der „Alone in the Dark“-Serie (1992-1994) ist der Blick durch ein Fenster auf die Spielfigur, die die Szenerie betritt. Obwohl technisch gesehen kein Unterschied zur Third-Person-Perspektive des restlichen Spiels besteht, sorgt die dramaturgische Platzierung der Kamera hier dafür, dass der Spieler gedanklich für einen kurzen Moment seine Figur verlässt und in die Perspektive eines unbekannten Dritten schlüpft. Zwar wird der Beobachter selbst nicht direkt gezeigt, doch verdichtet die herabblickende Kamera das unheimliche Gefühl, in dem scheinbar verlassenen Herrenhaus bereits erwartet zu werden.

    Weil „A Room Beyond“ ebenfalls auf statischen Kameraeinstellungen beruht, ist es um so wichtiger, die Räumlichkeit der Szene mittels Texturen, Objektanordnung und Beleuchtung auszudrücken. Einige Lichtinformationen, vor allem Lichtkanten, Schlagschatten und leuchtende Flächen, sind dabei bereits direkt in die Texturen eingezeichnet (Abb. 4).

    ​Abb. 4: Textur für den Innenraum eines Hauses. Pfeile markieren Lichter und Schatten, die bereits in Photoshop eingezeichnet wurden. Das heißt sie beruhen nur auf der Textur und keiner tatsächlichen Lichtquelle der Engine.

    ​Die endgültige Stimmung einer Szene hängt wesentlich von zusätzlich in der 3D-Szene platzierten Engine-Lichtquellen ab. Zumeist in Lightmaps gebacken, helfen sie, Licht und Schatten in Abhängigkeit von der jeweiligen Modell-Geometrie und der Platzierung aller Objekte in der Szene zu arrangieren. Nur wenige Lichtquellen kommen als solche in Echtzeit zum Einsatz, wo sie bewegliche Objekte wie Charaktere illuminieren. Neben der dramaturgischen Inszenierung können Lichter der Game-Engine auch helfen, die Plastizität und Klarheit von 3D-Modellen zu unterstreichen (Abb. 5, Abb. 6). Die Regeln cinematographischer Lichtsetzung, wie z.B. das Drei-Punkt-Beleuchtungsmodell, lassen sich problemlos in die virtuelle Bühne übertragen. Konträr gefärbte und in gegenläufigen Winkeln ausgerichtete Lichtquellen machen dann die räumliche Ausrichtung von Objektoberflächen durch unterschiedliche Färbung sichtbar. Infolge wirken dreidimensionale Objekte im zweidimensionalen Bild plastischer.

    ​Abb. 5: Game-Engine-Lichter steigern die Plastizität und Klarheit von 3D-Objekten.

    Abb. 6: Beispiel einer Gesamtbeleuchtung, die aus Texturdaten, gebackenen Lichtern und Echtzeitbeleuchtung entsteht.

    ​Bildebenen

    ​Mit teils transparenten Texturen versehene Ebenen (Planes oder Quads) und stark vereinfachte Gitternetzobjekte reichen in vielen Fällen aus, um die Szenenumgebung für ein Gameplay mit statischen Kameraeinstellungen zu gestalten. Photoshops Ebenen-Stile sind dabei ein effizientes Werkzeug, um Pixeldetails hinzuzufügen. In Abb. 7 wurden Architekturformen hauptsächlich durch einfarbige, manuell gezeichnete Ebenen realisiert. Die Anwendung von Ebenen-Stilen sorgt für zusätzliche Details wie Glanzlichter, Muster und Schatten. Der große Vorteil dieses Verfahrens liegt im Erhalt der Bearbeitbarkeit. Soll beispielsweise der Torbogen verändert werden, kann dies mit Buntstift- und Radiergummi-Werkzeug schnell und einfach bewerkstelligt werden. Alle Schatten, Lichtkanten, Muster und Verläufe passen sich automatisch an die neue Form an.

    ​Abb. 7: Viele Texturen wurden als einfarbige Ebenen angelegt. Details wie Rauschen, Muster, Licht- und Schattenkanten kommen durch Ebenenstile hinzu. Dies erhöht die visuelle Komplexität während die einfache Bearbeitbarkeit der Ebene erhalten bleibt, da durch ein- und ausschalten der Stile jederzeit zwischen den beiden Versionen gewechselt werden kann.

    Der Eindruck von Pixelgrafik entsteht einerseits durch die Verwendung von niedrig aufgelösten Quelltexturen, die in der Game-Engine skaliert werden. Andererseits eignen sich Ebenenstile wie die Musterüberlagerung dazu, um pixelige Strukturen, wie Rauschen oder Linienverläufe, beliebigen Formen und Flächen hinzuzufügen. Auch die Rauschen-Eigenschaft, die sich für Schatten- und Glühen-Stile einstellen lässt, trägt zur Verstärkung des Pixeleffekts bei.

    Abb. 8 zeigt eine Kameraeinstellung, die im Wesentlichen auf planen Texturebenen beruht. Eine Aufteilung in mehrere Geometrieobjekte ist dennoch nötig, damit sich die virtuellen Charaktere räumlich bewegen und beispielsweise um die Säulen herum laufen können (Abb. 8 oben). Alle Details und Dekorationen jedoch werden über Texturen realisiert, die schon beinahe dem endgültigen Bild entsprechen (Abb. 8 Mitte). Der abschließend angewandte Pixelierungs-Shader (Abb. 8 unten) richtet schließlich lediglich schräge und durch die Perspektive verzerrte Pixel in ein gerades Raster aus.

    Abb. 8: Szene, die auf Bildebenen basiert. ​Links: Mesh-Geometrie. Mitte: Direktes Rendering. ​Rechts: Postprocessing-Pixelierung.

    Grenzen und Herausforderungen

    Das Hauptrisiko der Kombination von Pixeltexturen und Postprocessing-Pixelierung liegt im Erscheinen von Interferenzen, die scheinbar zerbrochene Pixel generieren. Dies passiert vor allem dann, wenn Details auf die Darstellung durch einzelne Pixel angewiesen sind, da der Shader nicht zwischen gestalterisch wichtigen und unwichtigen Pixeln unterscheidet. Die Details des in Abb. 9 gezeigten Glasfensters sind allesamt in die Textur gezeichnet worden. Es kommt durch die unterschiedliche Größe der perspektivisch skalierten Texturpixel und der Auflösung des Postprocessing-Effekts zu einer unattraktiven Aufspaltung der einzelnen Texturpixel in mehrere kleinere Bildpunkte. Glücklicherweise gibt es für dieses Problem oft eine einfache Lösung: Da dieses Phänomen meist in herangezoomten Detailaufnahmen auftaucht, kann für die entsprechenden Kameras der Postprocessing-Filter schlicht deaktiviert werden (Abb. 9 rechts). Durch harte Kameraschnitte und eine ähnliche Größe der Pixel ist ein Unterschied zwischen nachträglicher Rasterung und skalierter Pixeltextur kaum wahrnehmbar. Leider funktioniert diese Maßnahme nicht immer. In einigen Blickwinkeln interpoliert der Shader z.B. die Augen der virtuellen Charaktere, die idealerweise über wenige einzelne Pixel darzustellen sind,  zu unscharfen Farbflecken (Abb. 10). Weil sich feste Pixelmuster für ausgewählte Modellpartien unter Beibehalt der räumlichen Transformationsfreiheit nur sehr schwer realisieren lassen, scheint dies ein Preis für diesen technischen Ansatz zu sein.

    Auch Kamerabewegungen unterliegen hier Einschränkungen. In traditioneller, handgezeichneter Pixelgrafik finden Kamerabewegungen oft in Form von verschobenen Ebenen statt. Dabei bewegen sich die Pixel nur horizontal und vertikal in der Kameraebene und nicht in der Tiefe. Bewegt sich jedoch eine perspektivische Kamera im Raum, so verändert sich der räumliche Blickwinkel auf alle Objekte, was dazu führt, dass alle Pixel nicht nur verschoben, sondern perspektivisch neu berechnet werden. Folglich ändert sich die Farbe von potentiell jedem Pixel, was ein Flackern des gesamten Kamerabildes zur Folge hat. Die Illusion von statischer Pixelgrafik geht dabei völlig verloren und das Herunterrechnen eines hochaufgelösten Bildes wird für den Spieler deutlich wahrnehmbar. Kamerabewegungen sollten daher auf das Verschieben des Ausschnitts eines einmal gerenderten und pixelierten Gesamtbildes beschränkt werden, um Pixelflackern zu vermeiden.

    Abb. 9: Befinden sich feine Details in der Textur, so kommt es beim Post-Processing zu Interferenzen (links). In einigen Fällen lässt sich dieses Problem durch Deaktivierung der Pixelierung und einer senkrechten Kameraperspektive lösen (rechts).

    Abb. 10: Kleine Details, wie z.B. die Augen des Charakters, die über einzelne Pixel dargestellt werden müssten, gehen durch die Postprocessing-Pixelierung verloren. Links: Screenshot aus dem Spiel. Rechts: gewünschtes Ergebnis (Bildmontage).

    Vorteile und Nutzen

    Die Vorteile der hier vorgestellten Kombination aus vorgefertigter Pixelgrafik und der nachträglichen algorithmischen Pixelierung liegen in Flexibilität und Dynamik, die der 3D-Raum mit sich bringt. Szenen lassen sich räumlich anlegen, was die Erstellung von verschiedenen Blickwinkeln auf die selbe Lokalität vereinfacht. Wenn sich die Requisite ändert, entfallen außerdem zusätzliche manuelle Korrekturarbeiten über mehrere Perspektiven hinweg.  Es bietet sich an, Spezialeffekte wie Explosionslichter, einfach über die Echtzeitlichtsetzung der Game-Engine zu realisieren. Die Kanten entlang der Objektgeometrie werden in die Berechnung von Licht- und Schatten ebenso einbezogen wie Bumpmap-Kanäle in den Texturen. Dynamische Objekte, wie z. B. Charaktere, können sich ohne zusätzlichen Implementierungsaufwand unter Einbeziehung von Licht und Kamerawinkel drehen, gestikulieren und frei in der Szene bewegen.

    Schließlich profitiert auch die Interaktion von der räumlichen Szene. Befindet sich die Spielfigur beispielsweise auf einer Anhöhe mit Blick ins Tal, so kann der Spieler auf das Tal klicken, um dorthin zu wandern. Da längere Distanzen in Spielen mit statischen Bildeinstellungen meist über mehrere Szenen hinweg verlaufen, muss die Programmierung dafür sorgen, dass die Spielfigur nun alle zwischen Anfangs- und Endpunkt liegenden Zwischenbildschirme durchwandert. Im Fall der klassischen Einzelbilderstellung ein aufwendiges Unterfangen. Dadurch dass dem Ansatz der halbautomatischen Pixelierung jedoch eine 3D-Szene zugrunde liegt, lassen sich Wegfindungsalgorithmen einsetzen. Bei Klick auf einen entfernten Punkt läuft die Spielfigur automatisch entlang des gefundenen Pfades bis zum Ziel. Auf dem Terrain verteilte Trigger schalten dabei zur jeweils geeigneten Kameraperspektive um.

    [kursbanner thema=“blender“]

    Blasphemie!

    Nun kann man natürlich diskutieren, ob die hier vorgestellte, teils automatisierte Pixelierung überhaupt noch zu dem zählt, was im Allgemeinen unter dem Begriff „Pixel-Art“ verstanden wird. Für Verfechter der reinsten Form stellt die manuelle Bearbeitung jedes einzelnen Pixels durch den Künstler ein essentielles Merkmal dieses Gestaltungsstils dar. Selbst einfache Filter und Werkzeuge sind manchmal schon verpönt.

    Obwohl ich glaube, dass halbautomatische Pixelierung durchaus dem Charme von rein handgemachter Pixelgrafik nahe kommen kann, bleiben einige deutlich sichtbare Unterschiede bestehen. So liegt es etwa in der Natur des Renderings frei beweglicher Objekte, dass unscharfe oder unattraktive Bildbereiche auftauchen können, was einen klaren Nachteil gegenüber handgemachter Pixel-Art darstellt. Algorithmische Glättungen, sei es in Form von Anti-Aliasing oder Bewegungsberechnungen, sehen immer ein Stück weit künstlicher aus als das Ergebnis filigranen Handwerks.

    Der hier vorgestellte Ansatz ist daher nicht als Ersatz zu verstehen. Vielmehr bildet er einen eigenen Stil, der sich eben gerade durch seine Unterschiede zu klassischer Pixel-Art abgrenzt. Ein gewisses Retro-Gefühl kommt dennoch auf, zumal Spiele wie Alone in the Dark oder Silver auch schon in der Pixel-Ära Mitte der 90er-Jahre mit der Kombination von statischem Bildmaterial und Echtzeit-3D-Objekten experimentierten.

    ​Nachtrag – ​Was mittlerweile geschah

    Als ich dieses Projekt 2015 begann, war der hier beschriebene Pixel-Effekt noch sehr neu. Mittlerweile gibt es aber eine Reihe von Projekten, die ​eine 3D-Szene in Pixel-Art zu verwandeln versuchen. Viele davon ​erreichen großartige Ergebnisse, ​perfektionieren ​das Verfahren und beheben sogar einige der ​oben beschriebenen Probleme. Ziemlich coole ​Ergebnisse liefert zum Beispiel das Stylizer-Plugin für Unity, das im AssetStore erhältlich ist.

    ​Beispiel des Stylizer-Plugins, das 3D-Szenen in Retro-Pixelart verwandelt.

  • FontAwesome-Symbole in Unity einbauen

    ​Ebenfalls interessant

  • Game-Binaries mit Versionsnummer versehen

    Game-Binaries mit Versionsnummer versehen

    Versionsnummern spielen bereits während der Entwicklung eine große Rolle, denn es muss feststellbar sein, in welchem Entwicklungsstand sich die gerade ausgeführte Software befindet. Am offensichtlichsten ist dies bei Aktualisierungen. Taucht beispielsweise ein Bug im Programm auf, so wird dieser behoben, eine neue Programmversion erstellt und veröffentlicht. Natürlich macht es nur Sinn, dass die Spieler auf die neueste Version Deiner Software aktualisieren. Dazu enthält jede ausführbare Datei eine Versionsnummer, mittels derer sich die aktuellste Datei ermitteln lässt.

    Aufbau einer Versionsnummer

    Diese Nummern bestehen in der Regel aus einer Zeichenfolge, die vier Nummern enthält, die durch Punkte voneinander getrennt sind, etwa:

    1.2.3.4

    1. Die erste Zahl ist der „Major“-Bestandteil, also die Haupt-Versionsnummer. Sie ändert sich meist nur über große Programmversionen hinweg, d.h. wenn sich die Inhalte der Software maßgeblich ändern. Beim klassischen Software-Kauf muss der Kunde normalerweise für jede neue Hauptversion bezahlen. Bei Spielen ist das nicht unbedingt der Fall, denn häufig ist ein Spiel ja ein einziges Produkt, das nur einmal gekauft wird und alle Updates kostenlos erhält. Erweiterungspakete, die viel neue Spielinhalte ausliefern, könnte man als kostenpflichtiges Major-Update realisieren. In der Praxis bewähren sich dafür aber eher separate Software-Module, z.B. in Form von DLCs. Ich habe in meinem episodischen Spiel A Room Beyond (kostenlose) Major-Updates bei der Veröffentlichung jedes neuen Kapitels eingesetzt, zumal alle Inhalte Teil der selben Spieldatei waren.
    2. Die zweite Zahl nennt sich „Minor“-Bestandteil, also Unterversionsnummer. Sie ändert sich öfter als die Major-Nummer und wird zum Beispiel verwendet, um Ergänzungen im Funktionsumfang einer Software zu veröffentlichen. Bei Anwendungssoftware sind Minor-Updates häufig kostenlos und Kunden erhalten beim Kauf die Zusage, dass sie mit der Einmalzahlung auch alle Updates bis zur nächsten Hauptversion (Major) kostenlos erhalten. Bei Games eignen sich Minor-Updates gut, um kleinere Ergänzungen, eventuell auch Fehlerbehebungen, zu veröffentlichen.
    3. Die dritte Zahl beschreibt den „Revision“-Bestandteil, auf deutsch etwa Überarbeitungsversion. Sie ändert sich oft und wird meist eingesetzt, um Fehler zu beheben. Automatische Updates über das Internet liefern häufig Revisions-Update aus, um Sicherheitslücken zu schließen und Programmfehler zu beheben. Weil diese Updates keine Funktionalität hinzufügen, sondern die Software nur warten, eignen sie sich gut, um z.B. im Hintergrund zu laufen.
    4. Die vierte Zahl beschreibt den „Build“-Bestandteil, also die Kompilierungsnummer. Diese Nummer ändert sich bei jeder einzigen Umwandlung des Quelltextes in eine  ausführbare Programmdatei. Sie gewährleistet, dass zwei unterschiedliche Kompilierungen (Builds) garantiert über unterschiedliche Versionsnummern verfügen und sich dadurch eindeutig unterschieden lassen. Meistens vergibt die Compilersoftware bereits automatisch Build-Nummern. Manchmal wird dieser Nummernteil aber wegen seiner eher schlechten Lesbarkeit weggelassen oder in der Programmoberfläche nicht angezeigt.

    Software-Aktualisierungen folgen nicht zwingend aufeinander. Die letzte Version einer Software sollte immer alle erforderlichen Aktualisierungen der älteren Versionen enthalten, was besonders relevant ist, wenn Aktualisierungsaktionen nötig sind. Wenn es zum Beispiel drei Versionen Deines Spiels gibt, 1.0, 1.1 und 1.2 und die letzten beiden Updates z.B. jeweils etwas am Format der vorhandenen Speicherstände verändern, so muss sichergestellt sein, dass ein Spieler, der Version 1.0 installiert hat und dann einfach auf 1.2 aktualisiert, auch die Korrekturen erhält, die normalerweise in Update 1.1 ausgeliefert werden.

    Assembly mit Versionsnummer versehen

    Wir können die Versionierungswerkzeuge, die das .net-Frameworks in C# bereitstellt, in Unity einsetzen, um unsere ausführbaren Spieldaten mit Versionsnummern zu versehen.

    [achtung title=“Beachte den Geltungsbereich“]Die hier beschriebenen Versionsnummern arbeiten auf Assembly-Ebene, d.h. für Untiy vereinfacht gesagt, dass jedes Modul bzw. jede DLL-Datei eine eigene Versionierung hat. Das ist dann besonders relevant, wenn Du Bibliothekscode in DLLs auslagerst. [/achtung]

    Du brauchst zunächst eine C#-Klasse, an die die Versionsinformation angehängt wird. Dazu eignet sich eine zentrale Klasse sehr gut, z.B. eine, die das Spiel insgesamt repräsentiert. Füge dann AssemblyVersion-Meta-Anweisung vor der Klasse ein und füge die Klausel using System.Reflection am Anfang der C#-Datei ein:

    ...
    using System.Reflection; //required for AssemblyVersion
    
    [assembly:AssemblyVersion ("1.0.*")] //TODO: Update version for each release
    public class MyClass: MonoBehaviour 
    {
    ...

    Als Parameter erhält AssemblyVersion eine Zeichenkette, die dem oben beschriebenen Versionsnummer-Muster entspricht. Zahlen (1.0) werden exakt in die Nummer übernommen, der Stern (*) wird vom Compiler automatisch mit der Build-Nummer ersetzt. Vor dem Erstellen einer neuen Major- oder Minor-Version müssen die festgeschriebenen Zahlen einfach manuell im Code erhöht werden.

    Erstelle das Ausgabeprojekt, z.B. als PC-Standalone-Fassung, über den Build-Befehl im File-Menü. Öffne den Ausgabeordner im Explorer/Finder und suche in den erzeugen Dateien dann die Datei Assembly-CSharp.dll. In den Datei-Eigenschaften ist die Versionsnummer zu sehen:

    Die dem Assembly hinzugefügt Versionsnummer. Die Build und Revisonskomponenten wurden automatisch gesetzt.
    Die dem Assembly hinzugefügt Versionsnummer. Die Build- und Revisonskomponenten wurden automatisch gesetzt.

    Versionsnummer im Code abfragen

    Natürlich können wir jetzt diese Nummer im C#-Code auslesen und entsprechend darauf reagieren. Dazu eignet sich die Klasse System.Version. Das für jede Klasse verfügbare Assembly-Objekt liefert eine Instanz der Versionsklasse:

    Debug.Log("Assembly-Version is "+typeof(MyClass).Assembly.GetName().Version); 
    // Output:
    // Assembly-Version is 1.0.6512.28670

    Außerdem lässt sich ein Versionsobjekt für eine Zeichenkette erzeugen:

    Version v = new Version("1.0.7000");

    Beachte, dass nicht alle Versionskomponenten angegeben werden müssen. In diesem Beispiel fehlt etwa die Build-Nummer (bzw. Revisions-Nummer, Erklärung folgt gleich).

    Man kann die einzelnen Versionsnummer-Bestandteile nun über die Eigenschaften des Versionsobjekts einzeln abfragen oder zwei Versionsobjekte miteinander vergleichen:

    Version av = typeof(MyClass).Assembly.GetName().Version;
    Debug.Log("Assembly-Version: "+av);
    Version v = new Version("1.0.7000");
    Debug.Log("v=" + v);
    Debug.Log("v.Major=" + v.Major);
    Debug.Log("v.Minor=" + v.Minor);
    Debug.Log("v.Revision=" + v.Revision);
    Debug.Log("v.Build=" + v.Build);
    if (v < av) Debug.Log("V is older than Assembly!");
    else Debug.Log("V is equal or newer than Assembly!");
    
    /*
    Output:
    Assembly-Version: 1.0.6512.29090
    v=1.0.7000
    v.Major=1
    v.Minor=0
    v.Revision=-1
    v.Build=7000
    V is equal or newer than Assembly!
    */

    Das Beispiel bringt zwei wichtige Erkenntnisse:

    • Undefinierte Versionsnummer-Komponenten erhalten den Wert -1, wodurch jede andere Version, selbst 0 in einem Vergleich als neuer bewertet wird (ist richtig).
    • Microsoft hat die Reihenfolge von Revision und Build vertauscht! Das ist eigentlich falsch, aber nicht zu ändern.

    Eine einfache Lösung für das Reihenfolge-Problem kann darin bestehen, Revision und Build gedanklich zusammenzufassen und die Versionsnummer so zu behandeln, als hätte sie nur die drei Stellen Major.Minor.Build. In der Praxis spielt die vierte Komponente dann einfach keine wesentliche Rolle mehr.

    Updates über die Versionsnummer entdecken

    Mit diesem Verfahren lassen sich nun der Aktualisierungsbedarf abfragen. Wenn das Spiel nicht über einen Client wie Steam ausgeliefert wird, sondern auf einem Webserver zum Download bereit steht, könnte man die auf dem Server hinterlegte Versionsnummer der Online-Version mit der Version des laufenden Spiels vergleichen. Ist die Version auf dem Server neuer, wird eine Update-Meldung angezeigt (oder das automatische Update gestartet).

    Ich empfehle Dir bereits während der Entwicklung, spätestens aber wenn erste Spieler testen/spielen, die aktuelle Versionsnummer der ausführbaren Datei im Spielstand mitzuspeichern. Das Spiel kann beim Laden eines Spielstandes dann die Version aus dem Savegame mit der Programmversion vergleichen und feststellen, wenn ein Spielstand mit einer älteren Spielversion gespeichert wurde. Manchmal kommt es vor, dass ein Programmfehler eine Korrektur von alten Spielständen erfordert. Das lässt sich auf diese Weise sehr einfach umsetzen.

    Versionierung und Mobile Games

    Das oben beschriebene Prinzip funktioniert auch für Handy-Spiele. Allerdings hat das App-Paket, dessen Version der Verwaltung durch App-Stores unterliegt, noch eine weitere separate Versionsnummer. Diese findet sich über das Menü Edit » Project Settings » Player und dann im Inspektor-Feld Version. Diese Nummer muss manuell gesetzt werden, spielt aber lediglich in der fertigen Version eine Rolle. Vor dem Build des Projekts muss diese Nummer also manuell angepasst werden, am besten auf ähnliche Werte wie die Assembly-Nummer.

    Dieser Wert lässt sich per Code übrigens über PlayerSettings.bundleVersion auslesen.

    [kursbanner thema=“csharp“]

    Zusammenfassung

    Zur Versionsnummerierung von ausführbaren Unity-Spielen kann die Assembly-Versionierung von .net zum Einsatz kommen. Das Auslesen von Versionsnummern, die in der Regel aus drei oder vier Zahlenkomponenten bestehen, ist in der Klasse System.Version bereits eingebaut. Das Vergleichen dieser Versionobjekte erleichtert die Umsetzung von Update-Vorgängen erheblich. Es ist anzuraten, die aktuelle Programmversion auch in Savegames zu hinterlegen, um auf in zukünftigen Versionen anfallende Wartungsläufe bereits von Anfang an vorbereitet zu sein.

    [bildnachweis]Beitragsbild: Designed by starline / Freepik [/bildnachweis]

  • GameDesign Document in Wikidpad stylen

    Gestern habe ich beschrieben, wie Wissensfragmente in WikidPad angelegt und strukturiert werden. Im folgenden schreibe ich über Aspekte der visuellen Aufbereitung.

    HTML-Vorschau

    Wie zuvor bereits kurz angesprochen, bietet WikidPad neben der Editor-Ansicht, die die Bearbeitung durch Hypertext-Funktionalität und einigen Basis-Formatierungen bereits erleichtert, noch eine HTML-Ansicht. In dieser wird eine Aufbereitung des Artikels angezeigt, die keine Wiki-Formatierungen mehr enthält. Zwar ist die Ausgabe schreibgeschützt, doch bietet sie dafür zahlreiche Möglichkeiten automatisierte Inhalte zu erzeugen oder die Ausgabe per CSS zu formatieren.

    Wikidpad HTML-Ansicht
    Wikidpad HTML-Ansicht

    Das HTML-Fenster kann verschiedene Browser-Implementierungen nutzen, um den aufbereiteten Inhalt anzuzeigen. Unter Windows empfehle ich den eingebetteten Internet Explorer zu verwenden, da dieser relativ viel CSS-Formate unterstützt – obgleich er in einem reduzierten Modus läuft und daher leider nicht der volle Formatsatz nutzbar ist.

    Der Internet Explorer muss zunächst (einmal pro WikidPad-Installation) in den Optionen eingestellt werden:
    Menü: Extras > Options > HTML Preview/Export > Preview Render: IE

    Beim Anlegen eines neuen Wiki-Worts wurde das Wort selbst als Überschrift in die neue Seite von der Software eingefügt. Jedoch mit zwei Pluszeichen (++), wodurch eine Überschrift auf Hierarchieebene 2 entsteht. Vermutlich hatten die Autoren einen Grund es so zu machen, den ich aber nicht nachvollziehen kann. In meinem Wiki möchte ich, dass die erste Überschrift immer auf Ebene 1 liegt. Nun kann man jede Überschrift von ++ einfach auf + ändern oder in den Einstellungen definieren, dass automatisch ein anderes Überschriftenformat beim Erstellen einer neuen Seite eingefügt wird.

    Um zu definieren, dass Überschriften auf neuen Seiten standardmäßig auf Ebene 1 liegen, folgendes einstellen:
    Menü: Extras > Options > Current Wiki > Headings > Heading Prefix: +

    Eigene CSS-Stile für die Vorschau einsetzen

    Das Aussehen des Textes in der HTML-Ausgabe lässt sich anpassen, in dem ein eigenes Stylesheet eingebunden wird. Dazu muss lediglich eine Datei namens wikipreview.css in den Unterordner data des Projektordners gelegt werden. Sie wird vollautomatisch eingebunden, wenn zwischen Editor- und HTML-Vorschau umgeschaltet wird.

    Über die üblichen CSS-Selektoren (body, p, …) bzw. die wikidpad-Klasse kann einerseits die grundsätzliche Erscheinung des gesamten Dokuments verändert, andererseits auch neue Elemente eingeführt werden. Weil HTML-Markup im Wiki-Wort-Quelltext erlaubt ist, bekommen z.B. mit <p class="eigeneKlasse">...</p> umschlossene Passagen eine beliebige Formatierung zugewiesen. Die nebenstehende Abbildung zeigt, wie sich z.B. farbige Markierungen nutzen lassen, um Textstellen hervorzuheben. Gelb könnte für noch zu überarbeitende Abschnitte, rot für kritische Stellen und grün für wichtige Entscheidungen im Spielkonzept angewendet werden.

    Hervorhebung mittels CSS
    Hervorhebung mittels CSS

    Bilder und Dateien einfügen

    Externe Dateien, z.B. Bilder oder sonstige Dateien, können in den Ordner files des Wiki-Projekts kopiert werden. Über den Code [rel://files/dateiname.ext] lässt sich dann ein Link auf die Datei erzeugen. Bilder werden in der HTML-Vorschau direkt als solche angezeigt.

    • Praktischerweise unterstützt WikidPad das direkte Einfügen von Bildern aus der Zwischenablage über die Tastenkombination Strg+V. Es wird dann eine Datei im files-Ordner sowie ein Einbettungscode im Dokument erzeugt.
    • Um Bilddateien in das Wiki-Projekt zu kopieren, kann die Datei mit gedrückter Strg-Taste in den Editor gezogen werden.
    • Um externe Dateien, d.h. Dateien außerhalb des Wiki-Projekts zu verlinken, lässt sich ein Link auf die externe Datei durch das Ziehen der Datei aus dem Dateiexplorer in den Editor (ohne gedrückte Taste) generieren.

    Umfangreiche Formatierungen von Bildern sind leider nur schwer möglich. Zwar lässt sich ein Bild durch Anhängen eines Skalierungsausdrucks an die URL zwar in der Größe verändern (z.B. [rel://files/plateau.png>r50%]), doch wäre eine Thumbnail-Funktion wünschenswert, die das Bild per Klick auf die Vorschau in voller Größe zeigt. Diese Funktionalität kann durch in Python formulierte Plugins erreicht werden, die sich im Ordner user_extensions der WikidPad-Installation befinden müssen. Mit meinem (minimalistischen) rbThumbs-Plugin (Download am Ende des Artikels) ist es etwa möglich, durch Einfügen des Codes [:thumb:Here]rel://files/plateau.png [:thumb:] eine Vorschaugröße des Bildes einzufügen, die sich per Klick auf die volle Größe entfaltet. Da das Script beim Klick auf das Bild im Grunde nur dessen css-Stil ändert, lassen sich Vorschau- und Vollbild-Ansicht leicht im CSS des Projekts anpassen.

    HTML-Templates nutzen

    Häufig ist es wünschenswert, die gleichen Textfragmente in jeder Seite eines Dokuments einzusetzen. Hier kommen Templates in Frage: In meinem GDD habe ich zwei Wiki-Words angelegt: HTMLHeader und HTMLFooter. Jede Wiki-Seite beginnt zudem mit [:page:HTMLHeader] und endet mit [:page:HTMLFooter], den Codes, die bei der Erstellung der HTML-Ansicht den Inhalt der Kopf- und Fußdatei an der jeweiligen Position einfügen. Durch Platzieren der in Teil 2 vorgestellten Formel [:rel:children] lässt sich so z.B. am Ende jeder Seite eine Liste ausgehender Links einbinden.

    Leider ist die Unterstützung für eigene JavaScript-Dateien, die sich in der HTML-Ausgabe nutzen ließen, nicht so einfach wie die CSS-Integration. Dennoch ist es mit ein bisschen Bastelei möglich, JS-Dateien zu integrieren. In meinem Beispiel habe ich den Import der Javascript-Datei im HTMLHeader platziert, so dass dieser etwas umständliche Code (siehe Download) nur einmal hinterlegt werden muss.

    Icons und Tree-Styles

    Neben der Aufbereitung des eigentlichen Dokument-Inhalts spielt die Präsentation in der Baum-Hierarchie eine entscheidende Rolle bei der Organisation des Konzepts. Durch Zuweisen von Stileigenschaften, wie z.B. Symbolen und Textformaten, lässt sich die Übersichtlichkeit der hierarchischen Struktur erheblich steigern. Beispiele für das Styling der Baum-Einträge sind folgende Codes, die wiederum jeweils als Meta-Tags in eckigen Klammern im Dokumentquelltext platziert werden:

    • [icon: carrot] ändert das Icon des Baumeintrags zu einer Karotte. Dieses Symbol verwende ich gerne für Gegenstände im Spiel (Items). Eine Liste aller möglicher Icons ist im Menü Format > Icon Name zu finden.
    • [bold: true] zeichnet den Text des Baumeintrags fett. Kann sich als nützlich erweisen, um beispielsweise übergeordnete Elemente hervorzuheben.
    • Die Kombination von hierarchischen Seiten und Icons ([icon: folder]) kann sogar verwendet werden, um Ordner anzulegen!
    • Tipp: Die WikidPad-Icons können auch im HTML-Seiteninhalt angezeigt werden: [:iconimage:carrot]
    Styling der Baumansicht
    Styling der Baumansicht

    Meta-Daten verstecken

    Abschließend fällt auf, dass die Metadaten in eckigen Klammern auch in der HTML-Vorschau sichtbar sind, was in aller Regel unerwünscht ist. Abhilfe schafft das Umschließen mit der Formel <<hide ... >>, die bewirkt, dass der eingeschlossene Text zwar verarbeitet wird, aber in der HTML-Vorschau nicht sichtbar ist.

    [kursbanner thema=“kreativ“]

    Zusammenfassung

    Wikidpad ist ein kleines OpenSource-Tool, um untereinander verlinkte Texte in lokalen Dateien zu organisieren. Die einzelnen Seiten bestehen aus Textdateien, die in Wiki-Syntax formatiert werden. Das Programm ist eine mögliche Alternative zu zahlreichen kommerziellen Tools, um Wissen zu organisieren und beispielsweise ein GameDesign-Document für ein kleines Team oder Ein-Mann-Projekte zu erstellen. Durch die Unterstützung spezieller Codes, Scripte und Stylesheets sind weite Teile der Software, des Inhalte und der Präsentation grafisch wie auch strukturell an eigene Wünsche anpassbar.

    [thrive_megabutton mt=“Download der Demo-Datei“ st=“Lade hier das im Artikel verwendete Wikidpad-Projekt herunter“ color=“blue“ link=“http://bit.ly/2hVFq6u“ target=“_blank“ align=“aligncenter“]

     

  • GameDesign-Documents mit Wikidpad erstellen

    Gestern habe ich beschrieben, welche Anforderungen Wissensfragmente eines Game-Design-Documents stellen und Gründe genannt, wieso sich z.B. WikidPad zur Wissensorganisation im Indie-GameDesign eignen kann. Im folgenden beschreibe ich einige Handgriffe, mit denen sich Einträge in WikidPad strukturieren lassen.

    Wissensfragmente bearbeiten

    Erzeugen eines neuen Eintrags mit hierarchischem Bezug.
    Erzeugen eines neuen Eintrags mit hierarchischem Bezug.

    Grundsätzlich besteht ein WikidPad-Projekt aus einer Sammlung von einfachen Textdateien, die in der Software bearbeitet werden können. Dabei kommen die üblichen Wiki-Formatierungscodes zum Einsatz, wodurch ein schnelles Erstellen von Seiteninhalten möglich ist. Für ein Game-Design-Document gehe ich so vor, dass ich jedes gedankliche Fragment (z.B. jeden Charakter, Schauplatz, Interaktionsobjekt, Story-Abschnitt, etc.) als separate Seite, d.h. als Wiki-Schlagwort, anlege.

    Zu beachten ist, dass Wiki-Seiten nicht alleine stehen können, d.h. sie müssen einer anderen Seite, im einfachsten Fall dem Projekt-Wurzeldokument, untergeordnet werden. Auf diese Weise entsteht ganz automatisch eine Hierarchie, da jedes Dokument ein Elterndokument hat. Ein neues Dokument/Wiki-Wort lässt sich anlegen und unterordnen, in dem in einem beliebigen anderen Dokument ein Link der Form [neuesWort] angelegt wird. Der WikidPad-Editor formatiert diesen Link, so dass bereits innerhalb des Editors per Doppelklick auf das Wort zu diesem navigiert werden kann. Die Abbildung rechts zeigt die Beschreibung des InGame-Objekts „Schatulle“, das als neues Wort der Wurzelseite hinzugefügt wurde. Im Navigationsbaum links wird die Hierarchie sofort abgebildet.

    Generell signalisieren eckige Klammern dem WikidPad-Parser die Definition von Metadaten. Der volle Funktionsumfang wird in der Programmdokumentation ausführlich besprochen und anhand von Beispielen illustriert. Als für GDD-Erstellung relevante Dinge möchte ich folgende Beispiele erwähnen:

    Verlinkungen

    • Links auf bestehende Artikel können wie oben beschrieben durch Setzen des Wiki-Wortes in eckige Klammern realisiert werden. Infolge erscheint das verlinkte Wort im Navigationsbaum an mehreren Stellen, was ein Vor- oder auch Nachteil sein kann. Sind eckige Klammern Teil des Inhalts verhindert ein Schrägstrich die automatische Verlinkung: [\Kein Wikiword]
    • Soll sich der Link-Text vom Wort unterscheiden, ist ein umbenennen per Pipe möglich: [Link|Anzuzeigender Text]
    • Absätze innerhalb eines Dokuments lassen sich mit [anchor:Ankername] erstellen. Links von anderen Seiten zu diesem Anker werden wie folgt formuliert: [Link]!Ankername
    • Durch [alias:alternativesWikiword] lassen sich alternative Dokumentnamen definieren, die als Linkziel dienen können.

    [kursbanner thema=“kreativ“]

    Schlagwort-Suchlisten

    Der Spezial-Eintrag „Views“ in der Baumstruktur enthält Wiki-Einträge, die nach speziellen Kriterien aufgelistet oder gefiltert werden. Über die Syntax [schlagwort:text] lassen sich hier auch explizite Elemente erstellen. WikidPad selbst sieht die Begriffe „todo“, „done“, „action“, „track“, „issue“, „question“ und „project“ vor, um etwa Bearbeitungszustände zu definieren. Enthält eine Seite z.B. den Code [todo: Design definieren], so erscheint ein Eintrag „Design definieren“ unterhalb des Knotens Views > ToDo. Der Eintrag selbst enthält wiederum einen Unterknoten, der auf das Dokument verlinkt, der das ToDo-Item enthält (siehe Abbildung unten links).

    ToDo-Item erstellen
    ToDo-Item erstellen

    Da aber nahezu beliebige Schlagworte möglich sind, kann der Mechanismus beliebig erweitert werden. So können  sowohl die Schatulle als auch die (darin enthaltene) Indianerpfeife im Beispiel den Code [quest: Pfeife finden] enthalten. Im View-Tree entsteht dann ein Views-Eintrag „Pfeife finden“ mit Unterknoten zu „Schatulle“ und „Indianerpfeife“, der zusammenfasst, dass diese beiden Elemente in die zu erledigende Spielaufgabe involviert sind.

    Eigene Filter erstellen
    Eigene Filter erstellen

    Relationen automatisch auflisten

    WikidPad bietet einige spezielle Codes an, um Daten dynamisch erzeugen zu lassen. Diese sind allerdings nur in der HTML-Vorschau, nicht der Bearbeitung selbst sichtbar. Nützlich finde ich unter anderem die Codes [:rel:childen] sowie [:rel:parents], die eine Auflistung allerdings WikiWords erzeugen, auf die die aktuelle Seite zeigt (d.h. Kind-Elemente) bzw. die auf die aktuelle Seite zeigen (d.h. Eltern-Elemente). Auf diese Weise lassen sich ausgehende und eingehende Verknüpfungen explizit generieren. In Kombination mit der Nutzung von Templates, die in Teil 3 dieser Artikel-Serie besprochen werden, können hier Beziehungen zwischen den Elementen in das Seitenlayout eingebaut werden.

    [seealso title=“Und morgen:“]Im letzten Teil erfährst Du mehr über die visuelle Aufbereitung der formulierten Wissensfragmente.[/seealso]

     

  • GameDesign-Documents für Ein-Personen-Projekte erstellen

    Wie organisiert man als Indie-Entwickler Ideen und Konzepte am besten? Während große Firmen auf komplexe netzwerkbasierte Systeme zurückgreifen können, scheint das für Indie-GameDesign, also sehr kleine Teams oder Ein-Mann-Projekte, übertrieben. Dennoch macht es auch im kleinen Rahmen Sinn, Konzepte strukturiert anzulegen und zu organisieren. Bisher habe ich letztlich einfach auf Dateiordner mit Bildern, Links, Dateien sowie Word-Dokumenten zurück gegriffen. In letzter Zeit hatte ich jedoch den Eindruck, dass es noch andere Ansätze geben müsste, die sich vielleicht besser eignen. Nach diversen Experimenten mit Online- und Offline-Tools bin ich momentan beim kostenlosen WikidPad gelandet. Im folgenden Artikel beschreibe ich einige Ideen und Gedankengänge zu Anforderungen und Lösungsmöglichkeiten der GameDesign-Dokumenterstellung für Indie-Spieleentwicklung.

    Hintergrund

    Ein Game Design Document (GDD) ist ein Dokument, das das Konzept eines Computerspiels beschreibt. Es gibt Auskunft über das Genre, das Design, die Geschichte und Charaktere, aber auch die Spielmechanik und ggf. sogar Details zur Projektorganisation und -planung. Ein GDC kann zu unterschiedlichen Zwecken eingesetzt werden. Einerseits kann es, wie z.B. auch das Storyboard, dazu eingesetzt werden, um anderen die Idee zu verkaufen. Dabei geht es manchmal darum Geldgeber oder Investoren zu finden oder manchmal auch um z.B. Produktions- und Projektpartner ins Boot zu holen. Im diesem Artikel zugrunde liegenden Fall war die Sache etwas einfacher: Ich schreibe GDDs zunächst hauptsächlich, um eine Idee für mich selbst zu entwickeln und Gedanken zu organisieren. Oft entwickeln sich Ideen über Monate oder Jahre hinweg und parallel zur Arbeit an anderen Projekten. Um den Überblick zu behalten, die Idee nicht zu verlieren und den Kopf trotzdem für neue Gedanken frei zu bekommen, ist es ratsam die Gedanken niederzuschreiben.

    Anforderungen

    Um so mehr Ideen zusammen kommen, um so komplexer wird die Angelegenheit und es tauchen einige Problem auf:

    • Gedanken sind fragmentiert. Ein Spieldesign besteht nicht nur aus einem einzigen großen Textbaustein, sondern aus vielen Elementen, z.B. Handlungsabschnitten, Charakteren, Schauplätzen, Spielobjekten, technischen und gestalterischen Richtlinien usw. Oft hat man einen einzelnen Gedanken zu einem solchen Element, der als Idee sofort festgehalten werden sollte. Das Spielkonzept besteht also letztlich aus einer Sammlung vieler einzelner Gedankenfragmente.
    • Gedanken sind multimedial. Die Handlung oder Spielmechanik kann zwar textuell formuliert werden, doch spielen Bilder und Mediendaten eine große Rolle in der Spielekonzeption. Zeichnungen und Skizzen sind ebenso wichtig wie konkreten Medienbeispiele (Moodsamples), die einen bestimmten emotionalen Eindruck widerspiegeln und zur gedanklichen Vorabvisualisierung der Idee essentiell beitragen. Ein Spielkonzept besteht also aus einer Sammlung von unterschiedlichen Medientypen.
    • Gedanken sind mehrfach und wechselseitig verknüpft. Die zuvor beschriebenen multimedialen Gedankenfragmente stehen miteinander in wechselseitiger Beziehung. Charaktere tauchen z.B. als Darsteller in Handlungsfragmenten auf und Inventargegenstände können an bestimmten Orten erworben werden. Für die grafische Gestaltung eines Orts liegen z.B. Bildbeispiele vor. Dabei sind zwei Eigenschaften wichtig: einerseits handelt es sich zunächst um 1:n-Beziehungen, d.h. ein Element kann auf mehrere andere Elemente zeigen. Beispielsweise kann eine Handlung auf Ort, beteiligte Personen und Regieanweisungen zeigen. Andererseits sollte diese Beziehung zumindest zu Organisationszwecken in beide Richtungen sichtbar sein. Die Beziehung Objekt → befindet sich an → Ort bedeutet umgekehrt Ort → enthält → Objekt. In einem Spielkonzept bestehen also inhaltliche oder organisatorische Beziehungen zwischen den Gedankenfragmenten.
    • Gedanken müssen überschaubar organisiert werden. Um nicht zu viel Aufmerksamkeit in die Verwaltung der einzelnen Fragmente stecken zu müssen und trotzdem den Überblick zu behalten, sollen die beschriebenen Inhalte auf eine Art und Weise präsentiert werden, die gut handhabbar ist und gleichzeitig die komplexe Datenmenge und ihre Beziehungen berücksichtigt. Schreibt man die Inhalte z.B. in ein Textdokument, so ist dieses gut überschau- und bearbeitbar. Hyperlinks und Strukturansichten ermöglichen zwar die Navigation zwischen den Segmenten doch bleibt die Linearität der Textanordnung statisch vorgegeben. Dateien wie z.B. Bilder sind, etwas in Word-Dokumenten, in der Datei enthalten und blähen diese auf. Organisiert man Bilder und Mediendateien als separate Dateien im Dateisystem so ist die Unabhängigkeit der Fragmente zwar gegeben, doch fehlt der Überblick sowie die Möglichkeit Metadaten zuzuordnen. Das Spielkonzept sollte also dynamische Abfragen unterstützen, die einzelne Fragmente ebenso unterstützt wie durch Filterung definierte Untermengen und Beziehungen zwischen den Elementen.
    • Sowohl die Eigenschaften relationaler Datenhaltung sowie die Handhabbarkeit einer lokalen Datei sollen gegeben sein. Ideal wäre also ein System, das das Hinterlegen von unabhängigen multimedialen Fragmenten und deren gegenseitige Verknüpfung unterstützt. Im Prinzip braucht man eine relationale Datenbank. Lösungen wie z.B. lokale oder entfernte MySQL-Webserver können eine Lösung sein. Jedoch stört mich daran, dass sowohl die Systemeinrichtung als auch das Sichern, Archivieren und Wiederherstellen von Projekten relativ aufwändig und umständlich ist. Für meine kleinen Konzeptprojekte bevorzuge ich daher eine lokale Anwendung, die Daten in lokalen Dateien vorhält. Diese lassen sich dann einfach über das Dateisystem handhaben, sichern und öffnen/schließen, was der Charakteristik eines lokalen Dokuments entspricht.

    [kursbanner thema=“kreativ“]

    WikidPad als Organisationswerkzeug

    Ich habe mehrere Werkzeuge ausprobiert. Microsoft’s OneNote geht z.B. in die richtige Richtung, scheint mir aber zu starr hinsichtlich der Formulierung von komplexeren Relationen zwischen Artikeln. Außerdem leidet das Tool unter den üblichen MS-Schwächen (z.B. Probleme mit relativen Links) und wirkt insgesamt recht unorganisiert. Lösungen wie Evernote bieten bessere Organisationsmöglichkeiten, speichern aber alles auf einem Webserver. Datenschutzfragen müssen hier ebenso bedacht werden wie die stetige Notwendigkeit einer Internetverbindung. Die Handhabung der eigentlichen Daten, deren Sicherung und Archivierung und Wiederherstellung liegt in der Software und erfordert ein gewissen Vertrauen in das Unternehmen.

    Letztlich bin ich bei WikidPad gelandet. Es handelt sich um ein OpenSource-Projekt, das in Python implementiert ist. Durch die Kompilierung zu einer ausführbaren Datei ist für den Endanwender jedoch kein Unterschied zu herkömmlichen Programmen bemerkbar. Wie der Name schon sagt, liegt das Ziel der Anwendung darin, die Mechanik eines Wikis mit der eines Notizbuchs zu vereinen. Sie arbeitet als lokales Programm, mit lokalen Dateien, die jedoch über die Programmoberfläche strukturiert präsentiert werden.

    [seealso title=“Und morgen: „]Im nächsten Teil zeige ich Dir konkrete Handgriffe zur Wissensorganisation mit WikidPad.[/seealso]

  • Bibliotheks-Code in mehreren Unity-Projekten nutzen

    Bibliotheks-Code in mehreren Unity-Projekten nutzen

    Sobald Du an mehreren Spiele-Projekten arbeitest, wirst Du feststellen, dass sich einige Code-Bausteine in allen Projekten ähneln. Meistens geht es dabei um spiel-unabhängig Hilfsmittel zur Erfüllung allgemeiner Aufgaben. In diesem Artikel nenne ich diese Scripte Bibliotheks-Code. Nun kann man die Dateien einfach in alle Projekte kopieren und so lokale Duplikate anfertigen, was sich vor allem dann anbietet, wenn ein Projekt abgeschlossen ist, zumal dabei lokale Kopien sogar nützlich sind. Sie stellen sicher, dass das Projekt in seinem zuletzt als lauffähig sichergestellten Zustand verbleibt. Werden jedoch mehrere Projekte quasi gleichzeitig weiterentwickelt, so ist es lästig, die veränderten, gemeinsam genutzten Dateien stets manuell zu synchronisieren. Da Unity nur Dateien in seinem lokalen Asset-Ordner einbindet und verlinkte Dateien nicht direkt unterstützt, bietet es sich an, diesen Vorgang zu automatisieren.

    Verhindere Konflikte durch Kapseln von Bibliotheks-Code in einer DLL

    Ich empfehle Dir, Deinen Bibliotheks-Code, der nur unabhängige Helferfunktionen beinhaltet und in mehreren Projekten zum Einsatz kommt, in eine separate DLL zu compilieren und diese dann in die Projekte zu kopieren. Dazu wird ein eigenständiges VisualStudio- oder MonoDevelop-Projekt angelegt, das den gesamten Bibliothekscode in eine DLL compiliert.

    Das bringt u. a. folgende Vorteile:

    • Der Code wurde beim Compilieren bereits geprüft. Du kannst daher ein Stück weit sicher sein, dass der Code grundsätzlich fehlerfrei ist (Logik- und Laufzeitfehler natürlich ausgenommen).
    • Es ist nur eine Datei zu verwalten, Du musst nicht mehrere Dateien, womöglich über mehrere Ordner verteilt, im Projekt verwalten. Werden Dateien gelöscht oder verschoben, so übertragen sich die Änderungen innerhalb der DLL automatisch. Das manuelle Löschen veralteter Dateien entfällt zum Beispiel.
    • Versehentlichem Verändern wird vorgebeugt, weil Du den Code innerhalb der DLL nicht direkt bearbeiten kannst. Bei einzelnen Dateien besteht ein größeres Risiko, dass Du Bibliothekscode bei der Programmierung veränderst und vergisst, diese Änderungen in die anderen Projekte zu spiegeln. Schlimmstenfalls entstehen dabei konkurrierende Versionen, beim Kopieren gehen Änderungen verloren oder Du musst mühsam verschiedene Änderungen zusammenführen.

    Ein Nachteil ist, dass Du ein zweites Projekt separat pflegen und die DLL-Datei in die Projekte kopieren musst. Fürs Kopieren beschreibe ich im nächsten Abschnitt unten eine Automatisierungsmöglichkeit.

    Anmerkung zur Alternative per Versionierung: Man könnte den gemeinsamen Code natürlich auch in einem Version-Management-System (z.B. CVS, SVN, GIT, …) ablegen und dieses in das Projekt importieren. Dabei importiert man allerdings möglicherweise auch unerwünschte Dateien, die als Unity-Assets interpretiert werden und verzichtet auf die oben genannten Vorteile.

    Dateiaktualisierung auf Knopfdruck

    Gehen wir also davon aus, dass Du jetzt ein oder mehrere Spiel-Projekt(e) hast, sowie eine Bibliotheks-Code-DLL  tools.dll, die in einem separaten Ordner liegt (z.B. als Ausgabe in einem eigenen VisualStudio-Projekt oder als Download eines entfernen cvs/svn/git/…-Repositories).  Du arbeitest jetzt in einem Unity-Projekt, das diese Datei nutzt und wann immer sie sich durch eine Aktualisierung ändert, soll die DLL im Untiy-Projekt möglichst auf die neue Fassung aktualisiert werden. Dazu kannst Du den FilePatcher des GameDev-Profi-Toolkits wie folgt einsetzen:

    Toolkit installieren

    • Lade die GDP-Editor-DLL gemäß dieser Anleitung herunter und kopiere sie in Dein Projekt.

    Lokales Editor-Profil anlegen

    • Führe den Menüpunkt Assets » Create » GameDev-Profi » Editor-Profile aus, um ein Profil-Asset anzulegen.
      Profil-Assets sind im Unity-Projekt gespeicherte Einstellungen, die nur für einen bestimmten Rechner oder Anwender gelten. Hier steht mehr dazu.
    • Wähle die neu erstellte Datei und klicke im Inspector auf den Schalter Activate, um die Datei als aktives Profil einzustellen.
      Screenshot der Profil-Aktivierung

    Kopiervorgang definieren

    • Kopiere die zu aktualisierende Datei zunächst einmal manuell in Dein Projekt, in dem Du sie aus dem Datei-Explorer/Finder in den Assets-Ordner ziehst.
    • Wähle die DLL in Unity aus und führe dann den Menübefehl Assets » GameDev-Profi » Add to FilePatcher in active Editor Profile aus.
      Bestätige die Rückfrage einfach mit Yes.
    • Wähle das aktive Editor-Profil aus. Du kannst das ganz einfach mit dem Menübefehl GameDev-Profi » Select active Editor Profile machen.
    • Im Inspector siehst Du jetzt, dass der Abschnitt File Patcher einen neuen Eintrag mit dem Projekt-Pfad der DLL enthält. Ergänze in diesem Eintrag im Feld with file den vollen Dateipfad zur Datei-Quelle, also der immer aktuellsten Version. Das ist z.B. das Ausgabe-Ergebnis im DLL-Projekt oder die Datei im Repository.
    • Aktiviere die Checkbox vor dem Wort Replace file, um den Eintrag aktiv zu schalten.
      Import von Bibliotheks-Code per FilePatcher-Konfiguration im Editor-Profil

    Kopiervorgang ausführen

    • Immer wenn Du nun eine neue Fassung der DLL kompilierst oder herunterlädst, kannst Du diese in Dein Projekt importieren, in dem Du den Menübefehl GameDev-Profi » Patch Files ausführst.

    Kurz zusammengefasst

    Der FilePatcher im GDP-Toolkit kopiert/ersetzt Dateien im Projekt mit Dateien aus dem Dateisystem. Welche Dateien wohin kopiert werden, ist in einem Editor Profile Asset hinterlegt.

    [bildnachweis]Beitragsbild: Designed by Freepik[/bildnachweis]