Sewer Adventures

Hallo,
Vor 3 Wochen habe ich an einem GameJam auf itch.io teilgenommen!
Ein Gamejam ist ein Wettbewerb, bei dem man in einer bestimmten Zeit ein Spiel zu einem bestimmten Thema entwickeln muss. Ich habe am Brackeys Gamejam 2021.1 teilgenommen, bei dem man eine Woche Zeit hatte um ein Spiel zum Thema Stronger Together entwickeln musste. Weil das mein erster Gamejam war, wollte ich in einem Team arbeiten, dass mir zeigen kann wie das alles abläuft. Ich habe ein tolles Team aus 3 Amerikanern und einem Engländer gefunden. Aus diesem Grund verlief die Kommunikation natürlich komplett auf Englisch, was sehr viel Spaß gemacht hat.

Ich werde in diesem Beitrag nicht erklären wie wir das Spiel entwickelt haben, weil ich noch Hausaufgaben machen muss. 🙂 Ich wollte euch nur den Link zum fertigen Spiel geben.

10k Leute hatten sich für den Jam registriert, doch nur 1980 Menschen haben ihr Spiel abgegeben, was wahrscheinlich auch daran lag, dass sich alle Mitglieder aus Teams registriert haben, aber nur eine Person des Teams tatsächlich abgegeben hat. So gesehen habe ich auch nicht abgegeben. Aber immerhin hat mein Team abgegeben. Und wir haben den 291. Platz belegt. Damit gehörten wir zu den besten 15% aller eingereichten Spiele!

Unser Spiel handelte von 3 Charakteren, zwischen denen der Spieler hin und her schalten konnte. Die Charaktere waren in der Kanalysation und mussten allerlei Abenteuer meistern. Dabei war jeder Charakter wichtig, denn er hatte eine spezielle Fähigkeit, die kein anderer hatte.

Mist! Jetzt fange ich doch schon wieder langsam damit an, von der Entwicklung zu erzählen. Naja hier ist der Link:

Unnoticed Devlog #4

Hallo Leute,
Auch in dieser Woche ist eine Menge passiert.

Gefahr für den Spieler

Zuerst habe ich Schießen auf den Spieler implementiert. Dafür habe ich eine Funktion geschrieben, die einen Ray auf den Spieler schießt. Wenn der Ray den Spieler trifft stirbt der Spieler. Diese Funktion wird durch invokeRepeating alle zwei Sekunden aufgerufen.

Dann habe ich einen mit SFXR erstellten Schuss-Sound hinzugefügt und mit einem Partikelsystem einen Muzzle Flash erstellt.

Am darauf folgenden Tag habe ich eine Todes-Animation für die Kamera erstellt und das Script so erweitert, dass die Animation bei einem Treffer des Gegners abgespielt wird und das Movement-Script des Spielers deaktiviert wird. Nun funktionierte das Schießen nur noch sehr merkwürdig. Der Gegner schoss überhaupt nicht mehr, nur wenn man ihn berührte würde plötzlich die TodesAnimation abgespielt.

Später fand ich heraus, dass invoke in der Update() Funktion nur sehr eingeschränkt funktioniert. Also erstellte ich mir mein eigenes Invoke. Dafür habe ich eine Variable erstellt, die wenn man sie auf 1 setzt jeden Frame um 1/120 Sekunde verringert wird. Wenn diese Variable 0 erreicht, wird die SchussFunktion ausgeführt. Damit schoss der Gegner schon mal wieder zuverlässig alle zwei Sekunden. Nur das Geräusch und der Muzzle Flash fehlten. Dieses Problem konnte ich auch schnell lösen.

Dann gab es noch das Problem, dass der Gegner perfekt zielen konnte man somit immer vom ersten Schuss des Gegners erfasst wurde. Zuerst dachte ich, dass ich das so lassen würde, denn in Unnoticed geht es ja schließlich darum unbemerkt zu bleiben und nicht darum dem Gegner zu entkommen. Schließlich habe ich mit meinem Vater darüber gesprochen und er sagte, dass der Gegner immer auf ein Objekt Taregt zielen sollte das dem Spieler zeitverzögert folgt. Somit ist es für den Gegner schwieriger den Spieler zu treffen wenn der Spieler sich viel bewegt. Diese Idee ließ sich dank Lerp sehr leicht umsetzten. Lerp ist eine Funktion, die einen Zwischenwert von zwei Floats oder Vektoren errechnet. Wen das interessiert, dem empfehle ich dieses YoutubeVideo. Mit dem Folgenden Script lasse ich das Target verzögert dem Spieler folgen.

public transform Player;
public float value = 0.2;
void Update(){
	transform.postion = Vector3.Lerp(transform.position, Player.position,  value) ;
}

So setzte ich die position des Targets in jedem Frame auf 20% zwischen der eigenen und der Spieler position. Jetzt wo ich so darüber nachdenke sollte ich das doch besser nicht jeden Frame, sondern jeden PhysikFrame tun, denn PhysikFrames werden immer nach einer einheitlichen Zeit ausgeführt. Also ersetzten wir Update einfach durch FixedUpdate. Denn sonst hätte der Gegner es schwerer zu zielen, wenn man auf besserer Hardware spielt. Ich denke allerdings, dass man dabei auch nicht so genau sein muss, schließlich sieht der Spieler ja von alldem garnichts.

Pause Menü

Ein paar Tage später habe ich ein PauseMenü erstellt. Das Problem ist nur, dass die Buttons aus irgendeinem Grund nicht funktionieren. Ich recherchierte und bemerkte, dass daran der FPS-CharacterController schuld ist. Der FPS-Controller hat in seinen Einstellungen eine BooleanVariable names Lock Cursor. Ich habe gelesen, dass ich diese wenn pausiert wird deaktivieren sollte. Bis jetzt schaffte ich dass allerdings noch nicht.

Builden von Version0.2

Nun dachte ich mir, ich sollte mal wieder eine Standalone-Version meines Spiels builden und diese hier hochladen. Als ich dies versuchte, erhielt ich einen Compilererror, der mich auf falsch gesetzte geschweifte Klammern in dem nicht von mir erstellten IK-Skript hinwies. Zu erst war ich verwundert, denn im Test-Modus entstand dieser Fehler ja auch nicht. Egal. Ich öffnete das IK-Script und sah mir die Klammern an. Mir fiel nichts falsches auf. Da der Compiler ja sagte etwas Stimme mit den (äußersten) Klammern nicht, probierte ich einfach aus noch eine Klammer hinzuzufügen oder wegzunehmen. Doch nichts half.

IK ohne IK

Zuerst war ich für ein paar Tage frustriert und arbeitete nicht weiter. Irgendwann recherchierte ich mal wieder ein bisschen zum Thema IK und fand etwas interessantes. Jemand benutzte statt Animation-Rigging oder anderem einfach ein transform.LookAt in der LateUpdate-Funktion. Dadurch wird in jedem Frame einfach nachdem der Animator seine Änderungen vorgenommen hat der transform eines Knochens so eingestellt, dass er direkt auf eine bestimmte Position zeigt. In meinem Fall auf den Spieler.

Am nächsten Tag probierte ich dies aus. Ich dachte ich müsste nur die Rotation des Oberarms verändern und die untereren Knochen auf 0 setzten, weil die Transformationsveränderung durch den Parent sich nicht auf die Werte der Transformation auswirkt. Damit lag ich falsch. Leider merkte ich das zu spät. Stattdessen probierte ich dieses ‘IK-System’ mithilfe von Offsets richtig einzustellen. Nach einer Menge Arbeit hatte ich den Oberarm so eingestellt, dass er immer in die Richtung des Spieler zielt. Nun versuchte ich den Unterarm und die Hand richtig rotieren zu lassen. Nach einer Weile gelang mir auch das. Doch als ich dies im Spiel ausprobieren wollte, fiel mir auf, dass der Unterarm nur aus einer bestimmten Perspektive funktionierte.

Gerade denke ich darüber nach, ob ich nicht auch Unterarm und Hand mit LookAt auf den Spieler zeigen lassen könnte. Das sollte ich vielleicht das nächste mal, wenn ich meinen Rechner an habe ausprobieren. Sollte das nicht klappen mache ich erstmal eine kleine Pause mit der Entwicklung von Unnoticed.

Am nächsten Tag

Ich habe das Problem jetzt lösen können. Mir fiel auf, dass ich bereits beim letzten mal versucht hatte alle Knochen mit LookAt auf den Spieler zeigen zu lassen.

UpperArm.transform.LookAt(target.transform);
UpperArm.transform.rotation= UpperArm.transform.rotation * Quaternion.Euler(offset);
LowerArm.transform.LookAt(target.transform);
LowerArm.transform.rotation = Quaternion.Euler(offset);
Hand.transform.LookAt(target.transform);
Hand.transform.rotation = Quaternion.Euler(offset);

Und? Habt ihr den Fehler gesehen? Richtig ich setzte fehlerhafterweise Hand und Unterarm zuerst auf die Rotation in Richtung Spieler und dann setzte ich die Rotation auf den Offset. Ich sollte mich echt schämen, dass ich an soetwas verzweifle.

Naja egal, Hauptsache ist, dass ich dieses Problem nun lösen konnte. So sieht dieser CodeAbschnitt jetzt aus :

UpperArm.transform.LookAt(target.transform);
UpperArm.transform.rotation erArm.transform.rotation= UpperArm.transform.rotation * Quaternion.Euler(offset);
LowerArm.transform.LookAt(target.transform);
LowerArm.transform.rotation = LowerArm.transform.rotation * Quaternion.Euler(offset);
Hand.transform.LookAt(target.transform);
Hand.transform.rotation = Hand.transform.rotation * Quaternion.Euler(offset);

Was Quaternion.Euler macht? Nun ja, in Unity werden Rotationen in Quaternions gerechnet. Deshalb muss ich mit Quaternion.Euler einen EulerWinkel in einen Quaternion umwandeln. Ein EulerWinkel besteht einfach aus x, y und z Achse einer Rotation. Ein Quaternion ist … ich habe keine Ahnung. Quaternions werden benutzt, weil EulerWinkel scheinbar sich scheinbar irgendwie sebst blockieren können. Wie das funktioniert wüsste ich auch gern.

Nun habe ich noch ein Boot in Blender modelliert, von dem aus der Spieler das Spiel startet und ein paar Textnachrichten, die dem Spieler helfen sollen. Nach alldem ist es Zeit für die Version 0.2! Übrigens habe ich diesmal auch einen WebGL build erstellt, damit ihr mein Spiel nicht downloaden müsst.

Blender Laden

Hallo Leute,
Vor ein paar Tagen habe ich ein Modulares Ladenhaus in Blender modelliert und gerendert.

Mein gerendertes Ladengebäude

Ja, ich weiß man kann sehen, dass nur die sichtbare Fassade modelliert wurde. Ich weiß wirklich nicht, warum ich unbedingt diese offene Tür haben wollte.

Ich hätte das Schanier der Tür natürlich auch auf die andere Seite setzten können aber das wäre auch inkorrekt. Was nun die beste Lösung gewesen wäre ist jetzt aber auch nebensächlich.

Ein weiterer interessanter Bestandteil dieses Renderings sind die Scheiben. Diese sind hellblau und haben eine weiße SubsurfaceColor. Dadurch entsteht dieser interessante Look.

Unnoticed Devlog #3

Hallo Leute,
In den letzten Tagen ist wieder sehr viel passiert.

Zuerst habe ich ein menschliches 3D-Modell in Blender eingefärbt, geriggt und animiert. Dieses Modell habe ich dann in Unity importiert. Dann habe ich dem Gegner die notwendigen Scripte hinzugefügt und geändert, damit sie die Animation korrekt abspielen. Jetzt habe ich einen Gegner, der sich nicht nur auf magische Weise bewegt, sondern einen Menschen, der sich laufend fortbewegt.

Der nächte Schritt war dann das Schießen auf den Spieler. Das war bis jetzt das größte Problem an der Entwicklung von Unnoticed. Zuerst wollte ich es mit Animation Rigging lösen. Animation Rigging ist ein von Unity entwickeltes Package, mit dem man Transformationen von Knochen eines Skeletts, das durch eine Animation angesteuert wird überschreiben kann. Ein guten Beispiel dafür ist ein Gegner der herum läuft, aber immer in die Richtung des Spielers guckt. Noch ein Beispiel ist ein Gegner der mit seiner Runnig Animation den Spieler verfolgt, aber dabei mit einer Hand, in der er eine Waffe hält immer auf den Spieler zielt. Letzteres ist exakt das, was ich erreichen möchte. Leider funktionierte Animation Rigging überhaupt nicht.

Dieses Problem bereitete mir sehr viel Frust und ich arbeitete erstmal für ein paar Tage nicht an Unnoticed. Dar das Schießen des Gegners ein fundamentaler Bestandteil des Spiel war, schien es mir nicht möglich einfach an diesem Problem vorbeizuarbeiten.

Aus diesem Grund begann ich verstärkte Recherche im Internet und fand eine andere Lösung : Fast IK. Fast IK ist ein Asset für Unity, mit dem es möglich ist einfach Inverse Kinematics kurz IK für ein Skelett zu erstellen. Nach ein wenig Recherche fand ich heraus, wie man mit Fast IK umgeht und wie ich es für meine Zwecke nutzen konnte. Mithilfe von diesem Assets habe ich in kürzester Zeit mein Problem gelöst.

Nun arbeite ich an der Umsetzung des Schießen des Gegners und vorallem an dem Design dessen.

Zudem habe ich schon ein kleines Menü erstellt. In der ersten Version von Unnoticed war der Hintergrund des Menüs ja komplett einfarbig. Dies wollte ich für die Nächste Version nicht mehr also öffnete ich die Umgebung meines Spiels in Blender und rendert schnell ein Bild davon. Blender rendert standardmäßig im 16:9 Format, das Standard Unity Format ist allerdings 4:3. Als mir dies auffiel dachte ich mir ging ich wieder in Blender um das Format umzustellen doch da kam mir eine Idee: Ein sich langsam verschiebender Hintergrund. Ich importierte das 16:9 Rendering in Unity und begann zu recherchieren, wie man in Unity animiert. Das war keine sonderlich schwierige Aufgabe. Zudem bräuchte ich keine einzige Zeile Code, denn Unity spielte meine Animation automatisch in dauerschleife ab. Exakt das, was ich wollte.

Unnoticed Devlog #2

Hallo Leute,
Gerade habe ich alle Probleme, die ich mit dem Gegner hatte auf ein Mal gelöst.
Das Problem war die Physik. Der Gegner ist auf dem hügeligen Gelände immer wieder abgerutscht. Dieses Problem habe ich gelöst, indem ich die Rigidbody Komponente auf Kinematic und das Gewicht auf 0.02 gesetzt habe.
Nun funktioniert der Gegner wieder hervorragend!

Zudem habe ich gerade in den Standard-Assets eine fertige FPS Touchbelegung gefunden, die ich in die Szene gezogen habe und die ohne weiteres dort sofort funktionierte. Schnell buildete ich das Spiel für Android und probierte es aus. Die Steuerung funktionierte nicht. Naja, egal.

Unnoticed Devlog #1

Hallo Leute,
Ich habe mir gedacht, ich könnte doch Devlogs zu meinem Projekt Unnoticed schreiben. Hier ist der Beginn dieser Serie.

Nachdem ich hier die erste Version veröffentlicht habe, dachte ich, dass ich das Spiel nochmal neu aufsetzte. Ich wollte mehrere Level haben, die alle in eine Open World implementiert sind.

Vor zwei Tagen habe ich mit dem Unity-Asset MapMagic2 herumgespielt. Ich merkte aber schnell, das die dabei entstandenen Maps zu realistisch waren. Erstens hatte mein PC Probleme damit und zweitens müsste ich dann auch die Gebäude in realistisch designen, wozu ich wahrscheinlich nicht in der Lage wäre.

„Unnoticed Devlog #1“ weiterlesen

Unity Golf

Hallo Leute,
Vor ein paar Tagen habe ich Unity geöffnet und ein bischen ausprobiert und schnell gemerkt, dass ich mit Unity viel besser klar komme als mit Unreal oder Armory. Nach einer Weile Funktionen ausprobieren und C# testen, stellte ich mich meinem ersten Projekt. Ich wollte ein simples 3D-Spiel entwickeln, in dem man ein Objekt steuert und versuchen muss ein anderes Objekt in ein Loch zu schubsen. Also im Prinzip Golf.

Ich schreib ein simples Movement-Skript. Dann wollte ich mal ausprobieren ein Spiel auf einem Mobil-Gerät zum laufen zu bringen und zu meiner Überraschung ging das erstaunlich leicht. Ich entwickelte weiter und hatte schnell die komplette Spiel-Logik zusammen.

Später habe ich diesem Spiel ein Menü-System hinzugefügt, mit dem ich auch ins ein nächstes Level springen könnte. Also öffnete ich Blender und modellierte ein paar einfache Maps. Nach ein wenig Feintunig hatte ich den Bogen raus und konnte schnell neue Levels erstellen und ins Spiel einbinden.

Website “Intro”

Hallo Leute,
Letztens habe ich mit Blender 2.8 ein “Intro” für Produktionen von dieser Website erstellt. Hier ist es :

Solltest du nichts sehen können, liegt das and der geringen Helligkeit.

Das neue Blender Auto

Hallo Leute,
Als ich gerade mit Blender Angefangen habe, habe ich ein Auto modelliert. Wenn ihr euch den Beitrag angesehen habt, dann wisst ihr, dass mir das eigentlich peinlich sein müsste. Aber es war ja auch einer meiner ersten Beiträge. Naja, letztens dachte ich, dass ich vielleicht noch ein Auto modellieren sollte. Dann könnte man den Fortschritt vergleichen. Also habe ich in Blender 2.8 dieses Auto erstellt.

Hier könnt ihr beide Bilder recht gut im Vergleich sehen