Gamedev Challenge - Breakout in 10 Minuten

Ich habe euch Spieleentwicklung in Unity versprochen, also sollt ihr Spieleentwicklung in Unity kriegen. Zugebenermaßen etwas anders, als ich mir das ursprünglich dachte, aber das soll mich erstmal nicht stören. Der Anlass ist, dass ich ganz gerne die Unity Tutorials von Brackeys anschaue und der vorletzte Woche eine “10 Minute Game Challenge” ausgerufen hat. Die Aufgabe ist, in 10 Minuten ein Spiel zu entwickeln, wobei vorbereitete Grafiken erlaubt sind. Selbst hat er einen minimalistischen Klon von Super Hexagon gebaut:

Ich fand die Idee gut und habe dafür tatsächlich zum ersten Mal seit vielen vielen Jahren ein richtiges Video aufgenommen hab. Sogar mit Facecam. Falls es jemanden interessiert, kann ich auch gerne mal einen Post darüber schreiben, wie mein Aufnahmesetup funktioniert (vielen Dank hier an poetBLUE und Björn the Smexy, die mich da beraten haben).

Aber zurück zum Thema… ich hab den Arcadeklassiker Breakout nachgebaut, wenn auch natürlich bei weitem nicht vollständig. Als Engine hab ich genau wie Brackeys Unity mit einem 2D-Szenensetup verwendet. Allerdings sind meine Objekte tatsächlich dreidimensional, weil Unity direkt über ein Kontextmenü Quader und Kugeln erstellen kann, aber keine zweidimensionalen Rechtecke und Kreise. Dafür hätte ich Sprites vorbereiten müssen und nachdem ich schon über eine Stunde damit zugebracht hatte, Unity zu aktualisieren und meine Aufnahme einzurichten, hatte ich darauf echt keine Lust.

Ich gestehe, dass ich das meiste, was ich in dem Video mache, vorher schonmal Off Screen ausprobiert habe. Allerdings habe ich alles aus dem Gedächtnis nochmal neu gebaut und auch ein paar Sachen anders gemacht, als im ersten Versuch, also zählt das, oder? Leider habe ich die 10 Minuten trotzdem nicht ganz eingehalten. Das Ergebnis könnt ihr übrigens dank WebGL auch direkt im Browser spielen:

Um Zeit zu sparen, habe ich mich ziemlich auf die eingebaute Physikengine verlassen, auch wenn die viel mehr tut, als ich für so ein einfaches Spiel bräuchte. Um keine Probleme mit Reibungsverlusten zu kriegen, hab ich Physics Material mit Dynamic Friction = 0, Static Friction = 0 und Bounciness = 1 erstellt und großzügig auf alle Spielelemente angewendet. Der Ball behält also alle Energie, egal mit was er kollidiert. Ursprünglich wollte ich Bounciness auf einen Wert größer als 1 setzen, damit der Ball jedes Mal, wenn er abprallt, etwas schneller wird, aber leider lässt Unity das nicht zu.

Der Code hinter dem Spiel ist so kurz, dass ich ihn in voller Länge hier einbinden könnte. Ich kürze ihn aber zumindest so weit, dass kein unnötiger Schrott wie nicht benötigte Usings, Standardkommentare oder leere Methoden drin sind.

using UnityEngine;

public class Ball : MonoBehaviour {
    void Start ()
    {
        var rigidbody = GetComponent<Rigidbody>();
        rigidbody.velocity = new Vector3(0, 10f, 0);
    }
}

Der einzige Code, der für den Ball ausgeführt wird, sorgt dafür, dass er beim Spielstart gerade nach oben beschleunigt wird. Nicht weiter spannend.

using UnityEngine;

public class Paddle : MonoBehaviour
{
    private float _movement;
    
    void Update ()
    {
        _movement = Input.GetAxis("Horizontal");
    }

    void FixedUpdate()
    {
        transform.Translate(_movement * Time.fixedDeltaTime * 15f, 0, 0);
    }

    void OnCollisionEnter(Collision collision)
    {
        collision.rigidbody.velocity += new Vector3(_movement, 0, 0);
    }
}

Der Schläger ist ein bisschen komplexer, aber nicht viel. Das Bewegen hätte man vielleicht noch von FixedUpdate in Update verschieben können, um Zeit zu sparen, aber so ist es sauberer und ich speichere _movement ohnehin, um es bei einer Kollision auf die Geschwindigkeit des Balls zu addieren. Das ist die simpelste Möglichkeit, um dafür zu sorgen, dass der Spieler die Flugrichtung des Balls beeinflussen kann. Deutlich eleganter wäre hier aber, zu prüfen, wo sich der Ball relativ zur Mitte des Schlägers befindet. Das ist weniger fummelig und simuliert in etwa einen Schläger mit einer leicht gebogenen Oberfläche. Außerdem sollte die Bewegung des Schlägers beschränkt werden, damit er das Spielfeld nicht verlassen kann.

using UnityEngine;

public class Brick : MonoBehaviour {
    void OnCollisionEnter(Collision collision)
    {
        Destroy(gameObject);
    }
}

Ganz unspektakulär: wenn irgendwas mit einem Stein kollidiert, wird er entfernt.

using UnityEngine;
using UnityEngine.SceneManagement;

public class Bottom : MonoBehaviour {
    void OnTriggerEnter(Collider collider)
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }
}

Am Boden befindet sich ein unsichtbarer Block mit Is Trigger = true, was bedeutet, dass er Kollisionen registriert, aber nichts von ihm abprallt. Den Trick, wie man für ein Game Over in einer Zeile die Szene neu lädt, habe ich tatsächlich aus dem Challenge Video von Brackeys gelernt. Sehr nützlich für so eine Challenge und auch ein paar andere Teilnehmer (z.B. Sykoo) verwenden das.

Insgesamt bin ich ganz zufrieden und werde vielleicht sogar irgendwann nochmal ein bisschen Zeit investieren, um das Spiel tatsächlich so weit zu kriegen, dass es Spaß macht. Deshalb hier schonmal eine kurze Liste, was ich alles ändern oder ergänzen könnte:

So oder so dürft ihr euch gerne herausgefordert fühlen, auch mal ein Spiel in 10 Minuten zu entwickeln. Schickt mir das Ergebnis auf jeden Fall oder noch besser nehmt ein Video auf, so wie ich.

Wake Me Up When Sheptember Ends

Dieser Post hat ausnahmsweise mal wenig mit den eigentlichen Themen dieses Blogs zu tun, aber er bezieht sich auf ein Erlebnis vor ein paar Stunden, das mich irgendwie zum Schmunzeln gebracht hat.

Als ich vorhin zum Kochen in der Küche stand, hab ich nebenher durch meine Youtube Abos geblättert und das neuste Floppotron Video gefunden, das so ein bisschen zum heutigen Datum passt:

Aus Spaß hab ich Kate, die am anderen Ende der Küche stand, ob sie erkennt, welcher Song das ist. Ihre Antwort kam wie aus der Pistole geschossen: “Wake Me Up When Sheptember Ends”. Ich dachte erst, sie macht einen Scherz, aber sie hat darauf beharrt, dass die Version, die sie früher immer im Radio gehört hat, eben diesen Sprachfehler hat.

Ich wollte ihr erst nicht glauben und in der Tat, der Radio Edit hat da ganz klar “September” und nicht “Sheptember” und die Albumversion klingt nicht anders:

Nachdem ich noch mehrere Album- und Best-Of-Versionen durchprobiert habe, Kate langsam an ihrem Gedächtnis gezweifelt hat und sie sogar in den Keller gestürmt ist, um das Album zu suchen, sind wir dann tatsächlich über die Version mit “Sheptember” gestoplert - die Liveversion auf dem Album “Bullet in a Bible”:

Da hört man tatsächlich gleich mehrfach “Sheptember”. Da ich keine Ahnung habe, ob der Sänger von Green Day an einem entsprechenden Sprachfehler leidet oder ob das einfach nur Unachtsamkeit war, will ich mir jetzt kein Urteil bilden, aber ein bisschen merkwürdig ist es schon. Auch, dass sich Kate nach all den Jahren noch an sowas erinnert.

Making of: die Technik hinter We Call It 42

Wie versprochen möchte ich als ersten richtigen Artikel ein bisschen was über die Technik hinter We Call It 42 erzählen. Ich werde mal versuchen, das so zu formulieren, dass es einerseits auch für interessierte Laien verständlich, andererseits aber auch für jemanden, der das nachbauen will, ausführlich genug ist. Entsprechend werde ich auch ein paar Sachen verlinken, die für jemanden, der in der Materie drin ist, längst bekannt sein sollten.

Weiterlesen...

We Call It 42 ist zurück!

Nach vielen Jahren Auszeit liegt auf wecallit42.de endlich wieder eine richtige Seite mit Inhalt. Die alte Seite habe ich damals offline genommen, weil die Kommentare regelmäßig von Spammern überflutet wurden und ich eh keine Idee hatte, was ich schreiben soll. Vor ein paar Wochen hatte ich jetzt endlich mal wieder Lust, mich um die Seite zu kümmern und habe ein recht minimalistisches Design zusammengebastelt, das aber bestimmt im Lauf der Zeit nochmal überarbeitet und erweitert wird.

Weiterlesen...