-
Notifications
You must be signed in to change notification settings - Fork 0
Minigames
Minigames sind der Hauptteil unserer Gameplayloop.
Minigames sollen archäologische Ausgrabungen simulieren, um vom Grundriss eines Gebäudes/Distrikts, eine Rekonstruktion wieder aufzubauen. Es sollen verschiedene Minigames möglich sein, pro Gebäude/Distrikt spezifisch wählbar. Die Minigames sollen in einem Overlay UI angezeigt und gespielt werden. Nach erfolgreichem Abschließen, soll sich ein Artefakt freischalten, das Tagebuch dazu öffnen, und das Gebäude wieder aufbauen.
Diese Anforderungen konnten wir nicht ganz genau umsetzen. Statt einem UI das über der Levelszene liegt, ersetzt die Minigameszene die Levelszene einfach. Hier genauer beschrieben.
Minigames werden in einem eigenen Ordner in Assets/MiniGames
umgesetzt. Dabei benötigt jedes Minigame die folgenden Dinge:
- Eine Szene, in der das Minigame gespielt wird
- eine MinigameSO Instanz, der die Szene zugewiesen ist
- Optional: ein
*MinigameParams
Skript welches vonMinigameParams
erbt. Dies ist ein ScriptableObject von welchem dann Instanzen erstellt und konkrete Parameter definiert werden können.
Alle anderen Umsetzungsdetails sind mehr oder weniger egal.
In einer BuildingGroup
sind MinigameSO
und MinigameParams
des zugehörigen Minigames gesetzt.
public class BuildingGroup
{
public int groupId = -1;
public MinigameSO minigame;
public MinigameParams minigameParams;
}
Wird eine BuildingGroup geklickt, wird ein Event in LoadMinigameEventChannel
mit dem MinigameSO gefeuert und die MinigameParams in State.Instance.MinigameParams
gesetzt. Der SceneLoader lädt die entsprechende Szene, entlädt die aktuelle Levelszene und setzt State.Instance.ActiveMinigame
.
Nun spielt der Spieler das Spiel.
Ist das Spiel fertig, wird ein Event in MinigameSuccessEvent_Channel
gefeuert. Der SceneLoader entlädt die Minigameszene, lädt die Levelszene und setzt State.Instance.ActiveMinigame
zurück. Der CityState merkt sich, dass die BuildingGroup gespielt wurde, und die Buildings wechseln ihr Model von Ruine zu Aufgebaut.
Um ein neues Minigame zu erstellen, kann man das Szenen Template Assets/MiniGames/MinigameScene.scenetemplate
verwenden. Diese Szene speichert man dann in einem Ordner unter Assets/MiniGames/<neuer Minigame Ordner>
ab. Darin kann man nun das gewünsche Spiel entwickeln.
Um einen Container für sonstige Infos, die Minigames in Zukunft eventuell halten müssen, zu bieten, muss noch eine MinigameSO
Instanz generiert werden (ebenfalls im selben Ordner um alles beisammen zu halten). Das passiert über Rechtsklick im Asset Browser Create > Minigames > Minigame
. Ins SO Asset die Referenz zur Szene ziehen, einen Namen geben und eventuelle sonstige Daten ausfüllen. Dieses SO Asset kann dann verwendet werden, um das Minigame über das LoadMinigameEvent
zu starten.
Sollte das Minigame Parameter benötigen, ein *MinigameParams : MinigameParams
Objekt erstellen und die Parameter definieren. Die übergebenen Parameter sind dann im Code über
var parms = State.Instance.GetParams<*MinigameParams>()
erreichbar.
Einfaches "Tippe die Leertaste" Spiel um Funktionalität zu testen ohne ein komplettes Minigame implementieren zu müssen. Im finalen Spiel nicht verwendet.
TODO @Xanad0u
Nach diesem Tutorial implementiert.
Hier muss der Spieler ein Puzzel lösen, in dem Bilder von Artefakten in Blöcke geteilt wurden. Ein Block fehlt und die Anordnung wurde randomisiert. Man muss das Bild wieder richtig anordnen in dem man immer einen Block in das freie Feld bewegt.
Hier muss der Spieler Fragen zu Troja beantworten. Sehr ähnlich wie in unserem Textadventure, nur dass es klickbare Antwortmöglichkeiten statt einem Freitextfeld gibt.
Die Fragen sind in JSON Dateien in Assets/TextAssets
abgelegt und werden über die MinigameParams
übergeben. Die Struktur der Dateien sieht so aus:
{
"questions": [
{
"text": "Text der ersten Frage",
"answers": [
{
"text": "Antwort 1",
"isCorrect": false // gibt an ob das eine richtige Antwort ist
},
{
"text": "Antwort 2",
"isCorrect": true
}
]
},
{
"text": "Text der zweiten Frage",
"answers": [
{
"text": "Antwort 1",
"isCorrect": true
},
{
"text": "Antwort 2",
"isCorrect": false
},
{
"text": "Antwort 3",
"isCorrect": false
}
]
}
]
}