Blog

Alle Artikel

Erstellung eines Minispiels mit KI

Es ist kein Geheimnis, dass sich die IT-Branche ständig weiterentwickelt und ständig neue Technologien und Tools auf den Markt bringt. Die moderne Welt erlebt ein großes Wachstum im Bereich der künstlichen Intelligenz (KI), das viele Branchen umfasst. Die Welt der Technologie und des Gamings verändert sich schneller als je zuvor und die Integration von KI wird zur Norm. Deshalb müssen Spezialisten, aber auch Unternehmen im Allgemeinen, ständig auf der Hut sein, um neue Ansätze, Mechanismen und Möglichkeiten nicht zu verpassen.

Aus diesem Grund beschloss Alexander, ein Experiment durchzuführen – die Erstellung einer Minispielszene auf Basis von Unity mithilfe des GPT-Chats. Der Zweck dieses Experiments bestand darin, ähnliche Erfahrungen zu sammeln und zu verstehen, wie sehr Chat dazu beitragen kann, die Entwicklung solcher Projekte zu beschleunigen.


Fangen wir damit an. Als Grafik-Engine wurde Unity 2022.3.12f1 gewählt. Warum Unity? Erstens habe ich gehört, dass dies eine sehr beliebte Engine mit einer entwickelten IDE und gutem Support ist. Zweitens können Sie das Spiel sofort auf mehr als einer Plattform bereitstellen – zum Beispiel iOS und Android. Im Vergleich dazu ist es mit Apples nativem SpriteKit nur möglich, ein Spiel für die iOS-Plattform zu erstellen. Als KI wurde die kostenlose Version von GPT Chat 3.5 (nachfolgend Chat genannt) gewählt. Ich möchte gleich darauf hinweisen, dass ich bis zu diesem Moment weder mit dem ersten noch mit dem zweiten Erfahrung hatte. Aus Erfahrung hatte ich nur die Entwicklung auf iOS, aber dieses Experiment erschien mir umso interessanter.

Also, gehen wir der Reihe nach an. Zunächst habe ich folgenden Zwei-Punkte-Plan erstellt:

  • Suchen und folgen einem Tutorial zum Erstellen eines Spiels in Unity, um ein grundlegendes Verständnis des Themenbereichs zu erlangen.
  • Versuchen, ein ähnliches/anderes Spiel mit Chat zu erstellen 

Was den ersten Punkt betrifft, war es nicht möglich, ein passendes Tutorial für die Erstellung eines 2D-Spiels zu finden. Ein Handbuch für 3D fiel mir ins Auge. Nach den ersten Stunden des Experimentierens wurde mir klar, dass die Fortsetzung dieses Tutorials eine übermäßige Zeitverschwendung wäre. Erstens gab es einen erheblichen Unterschied zwischen den Versionen meiner IDE und der im Tutorial beschriebenen – viele Funktionen/Steuerelemente und ihre Speicherorte stimmten nicht überein. Zweitens wurde deutlich, dass das Handbuch zum Erstellen eines 3D-Spiels viele unnötige Informationen enthält, die im Experiment nicht benötigt werden. Nachdem ich ein erstes Verständnis von Unity erhalten hatte, beschloss ich, sofort zum zweiten Punkt überzugehen und mit der Entwicklung meines eigenen Spiels zu beginnen, allerdings mit Chat.

Die Idee für das Spiel war die einfachste: eine Szene zu schaffen, auf der ein Held links auf dem Bildschirm auf und ab fliegt. Mit dem Klicken und Halten geht es nach oben, und mit dem Loslassen geht es nach unten. Der Held muss automatisch schießen. Auf der rechten Seite (von zufälligen Punkten entlang der Y-Achse) sollten Monster herausfliegen und sich auf den Helden zubewegen. Wenn eine Kugel ein Monster trifft, sollte es verschwinden. Außerdem musste der Hintergrund für die Szene ein endlos scrollender Hintergrund sein.

Zu meiner ersten Frage – „Wie erstellt man so ein Minispiel?“ (Angesichts der obigen Beschreibung) Der Chat antwortete mit einer Liste von Schritten mit einer kurzen Beschreibung der einzelnen Schritte: „Definieren der Spielmechanik, Auswählen einer Sprache und Entwicklungsumgebung, Erstellen von Grafiken, Entwicklung der Spiel-Engine, Benutzeroberfläche, Testen, Veröffentlichen, Marketing und Werbung, Support und Updates“.

Dies geschah mehrmals in verschiedenen Variationen – mir wurde klar, dass ich mit allgemeinen Anfragen nicht viel von ihm bekommen würde. Ich erinnerte mich an das Material aus dem Tutorial zum 3D-Spiel und versuchte, die große Aufgabe in kleine zu unterteilen:

  • Erstellen eines „Helden“-Objekts mit der erforderlichen Bewegungsphysik
  • Dem „Helden“ die Möglichkeit hinzufügen, „Kugeln“ abzufeuern. 
  • Erstellen eines „Monster“-Objekts mit der erforderlichen Bewegungsphysik
  • ein Monster verschwinden lassen, nachdem es eine Kugel getroffen hat
  • Erstellen eines Hintergrunds mit Infinity-Scrolling
  • Bilder für alle Objekte hinzufügen 

Danach bekamen meine Anfragen für den Chat eine andere Bedeutung und er begann damit, spezifischen Code und Aktionen zu erzeugen.

Hier sind die Arbeiten Schritt für Schritt voranschritten.

Schritt 1 – Erschaffung eines „Helden“

Zunächst habe ich ein leeres Modell/Objekt erstellt und es meiner Szene hinzugefügt. Danach war es notwendig, das Verhalten des Helden in einer speziellen Datei mit einem Skript (C#) zu beschreiben. Ich habe folgende Anfrage im Chat erstellt::

Anfrage – „Schreibe ein Skript, um ein Objekt mit Klicken und Halten anzuheben“ 

Antwort –

‘using UnityEngine;

public class LiftObject : MonoBehaviour

{

    private bool isTapping = false;

    private Vector3 initialPosition;

    public float liftSpeed = 1.0f; // Швидкість підйому об'єкта

    void Update()

    {

        if (Input.touchCount > 0)

        {

            Touch touch = Input.GetTouch(0); // Припускаємо, що використовується перший дотик

            if (touch.phase == TouchPhase.Began)

            {

                isTapping = true;

                initialPosition = transform.position;

            }

            else if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)

            {

                isTapping = false;

            }

        }

        else

        {

            isTapping = false;

        }

        if (isTapping)

        {

            // Поднимаем объект вверх

            Vector3 newPosition = transform.position + Vector3.up * liftSpeed * Time.deltaTime;

            transform.position = newPosition;

        }

    }

}

In diesem Skript prüfen wir, ob der Benutzer auf dem Bildschirm gedrückt hält. Wenn dies der Fall ist, dann wird das Objekt mit der angegebenen Geschwindigkeit „liftSpeed“ nach oben steigen. Wenn der Benutzer den Bildschirm loslässt, stoppt der Anstieg.

Um dieses Skript zu verwenden, hängen Sie es einfach an ein Objekt in Unity an. Sie können die LiftSpeed ​​​​auch anpassen, um zu steuern, wie schnell das Objekt ansteigt.

Um Ihnen Zeit zu sparen, werde ich außerdem keine Codebeispiele bereitstellen – es werden lediglich Anfragen und allgemeine Antworten angezeigt.

Da ich noch nie zuvor mit Skripten für Objekte gearbeitet hatte,ich fragte ich:

Anfrage – „Wie hänge ich ein Skript an ein Objekt/Sprite in Unity an?“

  • Erstellen Sie ein neues Skript: Öffnen Sie Ihr Projekt in Unity. Klicken Sie im Bereich „Projekt“ mit der rechten Maustaste auf den Ordner, in dem Sie das Skript erstellen möchten. Wählen Sie „Erstellen“ -> „C#-Skript“ (wenn Sie C# verwenden) oder „Erstellen“ => „JavaScript“ (wenn Sie UnityScript verwenden).
  • Passen Sie das Skript an: Benennen Sie das Skript entsprechend seinem Zweck um, indem Sie mit der rechten Maustaste darauf klicken und „Umbenennen“ auswählen. Doppelklicken Sie auf das Skript, um es in der IDE Ihrer Wahl zu öffnen (z. B. Visual Studio oder Visual Studio Code).
  • Hängen Sie ein Skript an ein Sprite an: Gehen Sie zu der Szene, in der sich Ihr Sprite befindet. Wählen Sie im Fenster „Hierarchy“ das Sprite aus, dem Sie das Skript anhängen möchten. Suchen Sie in der Komponente „Inspector“ im rechten Bereich den Abschnitt „Add Component“. Geben Sie den Namen Ihres Skripts in das Suchfeld ein und wählen Sie es aus der Dropdown-Liste aus. Ihr Skript ist nun an das ausgewählte Sprite angehängt. Sie können mit der Bearbeitung des Skripts beginnen und diesem Sprite Logik und Interaktion hinzufügen. Wenn Sie die Szene ausführen, wird das Skript durch Interaktion mit dem Sprite oder gemäß Logik ausgeführt.“

Wie wir sehen können, hat der Chat nicht nur die Abfolge der Aktionen vorgeschlagen, sondern auch beschrieben, wie man mit der IDE selbst arbeitet, was für mich als Anfänger in der Anfangsphase sehr nützlich war.

Nach dem Start des Programms stellte ich fest, dass der Held nur durch langes Tippen aufstehen kann, aber nicht runtergeht, wenn der Nutzer seinen Finger vom Bildschirm nimmt. Aber keine Fragen da – was angefragt wurde  – wurde auch geleistet )).

Anfrage – „Was sollte dem Skript hinzugefügt werden, damit das Objekt runtergeht, wenn kein Antippen erfolgt?“

Antwort – Chat hat ein Skript erstellt, das bereits zuließ, dem Objekt runterzugehen.

Als nächstes entdeckte ich, dass mein Held an extremen Punkten vom Bildschirm verschwinden kann

Anfrage – „Ändere das Skript, damit das Objekt nicht vom Bildschirm verschwinden kann“

Antwort – Chat hat das Skript mit neuen Einschränkungen umgeschrieben, aber aus irgendeinem Grund die Konstanten minY und maxY eingefügt, damit ich die Bewegung des Helden unabhängig einschränken konnte.

Nachdem ich ihn gefragt hatte, „eine Einschränkung nicht mit Konstanten, sondern mit realen Bildschirmgrößen hinzuzufügen“, erhielt ich ein Skript, das bereits alle Anforderungen für die erste Stufe erfüllte.

Schritt 2 – Hinzufügen der Option zum Abfeuern

Zuerst habe ich versucht, das Problem mit einer „magischen“ Anfrage zu lösen


Anfrage – „Das Objekt muss schießen“

Antwort – Chat hat dies auf seine Weise verstanden und das Skript des Helden aktualisiert – er hat ihm die Möglichkeit gegeben, sich in vier Richtungen auf dem Bildschirm zu bewegen und zu schießen, wenn eine Taste gedrückt wird.

Anfrage – „Nein, du musst das vorherige Skript verwenden, bei dem sich das Objekt nach oben/unten bewegen kann.“

Füge das automatische Abfeuern weißer Rechtecke von links nach rechts in Abständen von 0,5 Sekunden hinzu.“

Antwort – Chat hat das Skript korrigiert, aber das Ergebnis hat funktioniert, dass die Rechtecke nicht vom Helden wegflogen, sondern vor ihm auftauchten und nach rechts flogen.

Anfrage – „Berechne den Startpunkt des Rechteckflugs anhand der mittleren Höhe des aktuellen Objekts.“

Antwort – Chat hat ein neues Skript geschrieben und mir geraten, ein neues Objekt für das Bullet hinzuzufügen, weil der Held es beim Schießen verwenden wird.

Nachdem ich der Szene ein neues leeres Objekt hinzugefügt hatte, fragte ich Chat, ein Skript dafür zu schreiben, aber dann stellte sich heraus, dass die Kugel wie erforderlich von links nach rechts fliegt, sich aber gleichzeitig entlang der Y-Achse nach unten bewegt. Um das zu eliminieren, musste ich die Schwerkraftoption im Kugel-Objekt deaktivieren.

Der letzte Test in dieser Phase war die korrekte Position der abgefeuerten Kugeln, wenn sie den Bildschirm verlassen. Gemäß dem von Chat vorgeschlagenen Code hätten Kugeln in der Objektaktualisierungsfunktion (die ständig für jedes Objekt aufgerufen wird) zerstört werden sollen:

void Update()

    {

        // Знищуємо кулю, коли вона виходить за межі екрана.

        if (!GetComponent<Renderer>().isVisible)

        {

            Destroy(gameObject);

        }

    }

Leider trat beim Starten der Anwendung sofort ein Fehler auf: MissingReferenceException. Und wenn das Objekt nicht gelöscht wurde, blieb es im Speicher.


Alle Vorschläge von Chat bezüglich NULL-Prüfungen und deren Kombinationen mit Prüfungen wie isVisible waren erfolglos. Nachdem ich einige Zeit mit allen möglichen Variationen von Chat-Anfragen verbracht hatte, die mich im Kreis trieben, wandte ich mich an Google, wo es mir gelang, eine Lösung zu finden.

Für die Kugel war es notwendig, die Lebenszyklusfunktion des Objekts zu nutzen und darin einen Abschluss herbeizuführen, durch den das Objekt, dem die Kugel gehört (Held), es löscht.

void OnBecameInvisible()

    {

        // Wir prüfen, ob es Abonnenten für die Veranstaltung gibt und rufen diese auf

        OnBulletInvisible?.Invoke();

    }

Schritt 3 – „Monster“ hinzufügen

Um die Monster zu erstellen und zu animieren, habe ich im Wesentlichen die gleichen Schritte wie bei der  Kugel befolgt. Der einzige Unterschied bestand darin, dass die Kugel vom Helden gespawnt wurde und es notwendig war, dasselbe mit Monstern zu tun – ein eigenes Objekt für sie zu erstellen (MonsterSpawner), das sie „abschießen“ konnte.

Anfrage – „Wir brauchen Objekte (Monster), die von der rechten Seite auf den Bildschirm fliegen und entlang der X-Achse nach links fliegen.“ Das Spawn-Intervall der Monster beträgt 2 Sekunden.“

Antwort – Chat hat mir zwei Skripte angeboten – ein Skript für Monster (MonsterScript.cs) und ein Skript zum Erstellen von Monstern (MonsterSpawner.cs).

Anfrage – „Wo kann das MonsterSpawner-Skript verwendet werden? Kann es an einem Gegenstand befestigt werden?“

Antwort – „Ja, Sie können einem Objekt in Ihrer Szene ein MonsterSpawner-Skript anhängen. Erstellen Sie ein leeres GameObject, wählen Sie es in Hierarchy aus und hängen Sie dann ein MonsterSpawner-Skript an dieses Objekt an. Anschließend können Sie die Monster-Spawner-Einstellungen (z. B. Monster-Prefab, Spawn-Intervall usw.) über den Unity-Inspector konfigurieren.“

Als nächstes mussten wir das Monster töten.


Schritt 4 – Monster verschwinden lassen, nachdem es mit einer Kugel zusammengestoßen ist

Anfrage – „Monster sollten verschwinden, wenn sie von einer Kugel getroffen werden.“

Antwort – „Sie müssen Box Collider 2D zu Ihren Monstern und Kugeln hinzufügen, um Kollisionen zu erkennen.“

Der Chat schrieb außerdem zwei aktualisierte Skripte für die Kugel und das Monster, die die Kollision berücksichtigten, sowie ein neues Skript für den MonsterSpawner, der das Monster entfernte, wenn es kollidierte und der Clojure ausgelöst wurde. 

Ich habe ähnliche Manipulationen mit der Kugel gemacht – jetzt zeichnete sich bereits eine Szene ab.

Schritt 5 – Einen Hintergrund mit endlosem Scrollen erstellen

Für den Hintergrund habe ich mich entschieden, einen Druckbildschirm mit einem Sternenhimmel zu verwenden. Die Idee bestand darin, dieses Bild endlos, und vor allem, nahtlos entlang der X-Achse als Hintergrund für die Szene zu scrollen.

Anfrage – „Wie erstelle ich einen endlosen Hintergrund, der sich von rechts nach links bewegt?“

Antwort – „Um einen unendlichen Hintergrund zu erstellen, der sich von rechts nach links bewegt, können Sie zwei Instanzen des Hintergrunds nebeneinander verwenden und sie bei der Bewegung verschieben, um einen Unendlichkeitseffekt zu erzeugen.“

Die Option mit zwei Bildern hat mir nicht gepasst


Anfrage – „Ich muss aus einem Bild einen endlosen Hintergrund erstellen“

Antwort – „Um in Unity einen unendlichen Hintergrund aus einem einzelnen Bild zu erstellen, können Sie ein Skript verwenden, das die Hintergrundtextur entlang der horizontalen Achse verschiebt und so einen Unendlichkeitseffekt erzeugt.“

Der Hintergrund bewegte sich nicht. Im Chat wurde versucht, verschiedene Tipps zum Einrichten von Komponenten zu geben, aber es kam mir so vor, als würden sie mir nur im Kreis angeboten.

Als nächstes habe ich versucht, auf Englisch umzusteigen, weil ich gelesen habe, dass Chat es besser versteht und genauere Antworten gibt. Am Ergebnis änderte sich nichts – wir gingen weiter im Kreis.

Nach einiger Zeit habe ich mich an Google gewandt und dort eine Lösung gefunden. Für den unendlichen Hintergrund war es notwendig, ein Objekt eines völlig anderen Typs zu erstellen – Quad, ein Material dafür basierend auf meinem Bild zu erstellen und einen Shader mit einer Textur dafür auf eine bestimmte Weise zu konfigurieren.

Nach all dem bleibt wohl noch eine letzte Sache übrig:

Frage – „Wie stellt man sicher, dass sich die Kugeln nicht mit dem Hintergrund überschneiden?“

Antwort – „Um zu verhindern, dass die Kugeln durch den Hintergrund blockiert werden, können Sie das Ebenensystem in Unity verwenden. Stellen Sie sicher, dass sich Ihr Hintergrund und Ihre Kugeln auf unterschiedlichen Ebenen befinden, und passen Sie deren Ebenenreihenfolge so an, dass der Hintergrund unter den Kugeln liegt.“

Also habe ich die Z-Hierarchie für die Ebenen geändert und es hat funktioniert. Übrig bleiben nur noch die Bilder.

Schritt 6 – Bilder für alle Objekte hinzufügen

Ich brauchte Chat nicht mehr, um jedem Objekt Bilder hinzuzufügen. Das wusste ich bereits aus dem Tutorial. Das gewünschte Ergebnis habe ich erzielt, indem ich zu jedem Bild Sprites erstellt und diese an die gewünschten Objekte angehängt habe.

Schlussfolgerung

  • Der Chat beschleunigt den Entwicklungsprozess wirklich, indem er auf Anfrage vorgefertigte Skripte anbietet und ihnen in der Regel begleitende Anweisungen liefert – wie und welches Objekt hinzugefügt und konfiguriert werden soll.
  • Die Qualität der Antworten hängt direkt von der Qualität der Anfragen ab – je präziser die Anfrage mit Details und Nuancen ist, desto wahrscheinlicher ist es, dass die Chat-Antwort beim ersten Mal funktioniert
  • Der Chat konnte einige Probleme nicht lösen, ich musste selbst nach einer Lösung suchen – Memory Leaks, korrekte Bedienung des Infinity-Hintergrunds, Auswahl der richtigen Shader.
  • Um Minispiele zu erstellen, ist Unity-Kentnis erforderlich.
  • Es fühlt sich an, als ob Chat 20–30% der Entwicklungszeit einsparen kann. Für jede Art von Spiel müssen Sie verstehen, wie alles zusammenwirken soll und welche Nuancen es für verschiedene Fälle gibt.
  • Je höher Ihre Unity-Kenntnisse sind, desto effektiver können Sie mit Chat arbeiten.
  • Die Antwort aus dem Chat ist vollständiger, wenn die Anfrage klar und vollständig formuliert ist. Ich möchte darauf hinweisen, dass während des Experiments die kostenlose Version 3.5 verwendet wurde. Offensichtlich werden die Ergebnisse der kostenpflichtigen Version besser sein.

Autor: Alexander Bondar