2D Racer GUI und Gamelogik (Pt.4)

Das letzte mal haben wir NGui eingefügt die bestehende GUI ausgetauscht, Screens angelegt. Jetzt schauen wir mal was wir haben ich habe noch ein „Win Screen“ und ein „Start Up Screen“ eingefügt. hier mal ein Screenshot wie es aktuell bei mir in der Hierarchie im UIRoot aussieht.

UIRoot_1

Um diese GUI in den Skripten anzusprechen, werden in den bestehenden Skripten einiges hinzugefügt und neue Skripte erstellt. In diesem Teil bleibt der „Start Up Screen“ erst mal aussen vor. Der GameHud wurde im vorherigen Teil schon besprochen. Wir kümmern uns heute um den „Game Over Screen“, „Pause Screen“ und „Win Screen“.

Ich fange mit dem umfangreichsten Änderung an, den „Game Over Screen“. Für den muss einiges geändert werden, mal schauen was das „Crash Racer Framework“ schon vorbereitet hat.

Hier kann das Paket von Blue Monster Studio  an getestet werden als Webplayer Version. ver. Blue Monster StudioCrash Race Test

Nach dem Funpart zocken ;-). Hat sich herausgestellt das es eine Reset Funktion im Pause Menü gibt und eine Game Over Funktion in dem der Fahrer mit dem Kopf den Grund berührt, heisst diese Funktion springt nur an wenn der Trigger am den Boden mit dem Tag „Ground“ berührt. Kleine Anmerkung in der Demo Version hat der Ersteller kein visuellen Boden eingefügt sondern nur ein Polygon2D Collider mit dem Tag „Ground“. Ok die Game Over Funktion ist nicht schlecht kann man beibehalten, die Reset Funktion fliegt raus. Es fehlt auch eine visuelle Ansicht das dem Spieler anzeigt was passiert ist. Die Reset Funktion im Pause Menü und auch die von der Game Over werden am Ende beide auf einen Restart hinauslaufen.

Um den „Game Over Screen“ benötigt du eine Textur als Hintergrund, einen Titel, einen Status Label und zwei Buttons. Alle Objekte sollten Childs von der Hintergrund Textur sein, da ich das Menü animieren will. Was bedeutet an die Hintergrund Textur wird noch ein Tween Scale angefügt. Es soll von 0 zu 1 anwachsen, der Play Modus „Once“. Als nächstes werden zwei Skripte für die Buttons erstellt eines Restart.cs, SceneLoader.cs. Von den vorhandenen die CarDestroy.cs und CarGameManager.cs wird benötigt.

Der GameOver Screen

Die Restart.cs sieht so aus

using UnityEngine;
using System.Collections;

public class Restart : MonoBehaviour {

 	void OnClick ()
	 {
	 	Application.LoadLevel (Application.loadedLevel);
	 }
}

Die SceneLoader.cs sieht so aus

using UnityEngine;
using System.Collections;

public class SceneLoader : MonoBehaviour {

    public string sceneToLoad;
    public bool quitGame;
    
    
    void OnClick ()
    {
        if (!quitGame)
        {
            Application.LoadLevel (sceneToLoad);
        }
        else
        {
            Application.Quit ();
        }
    }
}</pre>

Jetzt komm ich zur CarGameManager.cs. Dort werden wir erst mal neue Variablen einfügen. Dann wird die void Reset() und die OnGui() entfernt.  Und eine neue Funktion eingefügt.

public GameObject gameOverScreen;
public UILabel crashText;

[HideInInspector]
public int deathState; // 0 = deaktiviert, 1 = SpeedReset, 2 = Crash

private bool isWin;

public void GameOver(bool gameOver)
    {
        if (gameOver && !isWin)
        {
            gameOverScreen.SetActive (true);
        }
        if (!isWin && gameOver && deathState == 1)
        {
            crashText.text = "You Drive to Slow!";
            crashText.enabled = true;
        }
        if (!isWin && gameOver && deathState == 2)
        {
            crashText.text = "Your Neck was broken!";
            crashText.enabled = true;
        }
        
    }

In der CarDestroy.cs werden neue Variablen eingefügt. Neue Funktionen und Funktionen umgeschrieben/erweitert. In diesem Skript ist auch der richtige Platz um die Game Over Funktion zu erweitern, wozu auch in der CarGameManager.cs die deathState Variable eingefügt wurde. Für die zweite Variante hab ich mir gedacht, das der Spieler immer in Bewegung bleiben soll. Heisst eine kurze Warnung wenn er zu langsam wird, wenn er kein Gas gibt. Game Over!

public float resetSpeed = 0.025f;
public UILabel warningText;
private TweenAlpha tweenText;
private float resetSpeedSqr;
[HideInInspector]
    public bool isStarted;

void Start ()
    {
        tweenText = GameObject.Find ("WarningText").GetComponent();
        gameManager = GameObject.FindGameObjectWithTag("GameController").GetComponent();
        resetSpeedSqr = resetSpeed * resetSpeed;
        playerCtrl = GetComponentInParent();
    }

void Update ()
    {
        StartCoroutine (SpeedReset ());
    }

public IEnumerator SpeedReset ()
    {
        if (isStarted && !Fire)
        {
            
            if (Car.velocity.sqrMagnitude < resetSpeedSqr)
            {
                warningText.color = new Color (255, 0, 0);
                warningText.text = "Go Go! Gaspedal on the Right Side!";
                tweenText.PlayForward();
                yield return new WaitForSeconds (2.5f);
                
                if (Car.velocity.sqrMagnitude < resetSpeedSqr)
                {
                    gameManager.deathState = 1;
                    Respawn ();
                }
                else if (Car.velocity.sqrMagnitude > resetSpeedSqr)
                {
                    tweenText.ResetToBeginning();
                    yield break;
                }
            }
        }
        
        yield return null;
    }

void Respawn ()
    {
        gameManager.GameOver (true);
        Vehicle.gameObject.collider2D.enabled = false;
        Car.isKinematic = true;
        playerCtrl.enabled = false;
        Debug.Log ("SpeedReset Ist aktiv " + gameManager.deathState);
    }

public IEnumerator OnFire ()
    {
        ...
        gameManager.deathState = 2;
        ...
    }</pre>

Die Restart.cs und SceneLoader.cs sind Button Skripte, so nenne ich sie jetzt mal, diese gehören an das Objekt gehängt an dem auch das Button Event Skript von NGui hängt. Der Collider sollte ebenfalls an diesem Objekt sein.

GameOverScreen_1

Der Pause Screen

Für den Pause Screen werden die ButtonSkripte benötigt, plus ein neues das nenne ich PauseClose.cs. Geändert wird die CarGameManager.cs. Ich fange mit der CarGameManager.cs an, da für das neue Skript ausschließlich Variablen aus dem Manager Skript genutzt werden. Das Menü wurde mit 3 Buttons ausgestattet ein Menü, ein Restart und ein Back Button.

Also im CarGameManager.cs werden wieder neue Variablen eingefügt. Und die bestehende Funktion SetPause umgeschrieben.

public GameObject pauseScreen;
public TweenAlpha pScreenBGAni;
public TweenAlpha pHudBGAni;
[HideInInspector]
public bool paused = false;

void Start ()
{    
    ...
    SetPause (false);
    ...
}

void Update ()
{
    if(Input.GetKeyDown(KeyCode.Escape))
    {
        if(paused)
        {
            SetPause(false);
        }
        else
        {
            SetPause(true);
        }  
}

// Pauses/unpauses the game
public void SetPause (bool pause)
{    
    if(pause)
    {
        paused = true;
        pauseScreen.SetActive (true);
        Time.timeScale = 0;
        pScreenBGAni.PlayForward();
        pHudBGAni.PlayForward();
    }
    else
    {
        pauseScreen.SetActive (false);
        paused = false;
        Time.timeScale = 1;
            
    }
}</pre>

Jetzt kann das neue Skript erstellt werden, da die Grundlage dafür geschaffen ist. Warum mache ist das so, da ich im Pause Screen ein Button einfüge der Back oder Close heisst. Dieser soll einfach nur den Pause Screen schliessen. So das man wieder weiter spielen kann.

 

using UnityEngine;
using System.Collections;

public class PauseClose : MonoBehaviour {

    private CarGameManager gameManager;
    
    void Start ()
    {
        gameManager = GameObject.FindGameObjectWithTag ("GameController").GetComponent();
    }
    
    
    void OnClick ()
    {
        gameManager.SetPause (false);
        gameManager.pHudBGAni.ResetToBeginning();
        gameManager.pScreenBGAni.ResetToBeginning();
    }
}

PauseScreen_1

 Der Win Screen

Für den Win Screen werden wieder 3 Buttons benötigt und ein Titel. Die 2 ersten Buttons sind wieder Menü und Restart das Setup ist wie bei den vorherigen Menüs. Dann kommt noch der Post Score Button hinzu. Mit diesem werde ich mich später in einem gesonderten Artikel kümmern. Jetzt geht es erst mal darum ein Gewinn festzulegen. Dazu wird ein neues Skript und ein neues GameObject erstellt und Änderungen in der CarGameManager.cs gemacht. Um den Gewinn zu triggern wird in diesem Fall eine Ziellinie benötigt. Diese hab ich mit einer Sprite gelöst, diese dann Multiple gemacht ,damit man sie zerschneiden kann. Die Sprite hab ich dann an in ein Empty abgelegt und wieder zusammen gebaut. Wichtig das auch ein BoxCollider2D an dem Objekt ist. mit einem aktiven Trigger.

ZielLine

An die Ziellinie gehört auch das neue Skript WinTrigger.cs. Vorher werden aber erst die Änderungen an der CarGameManager.cs gemacht. Dort werden wieder neue Variablen und eine neue Funktion eingefügt.

public GameObject gameOverScreen;
private bool isWin;

void Start ()
{
    ....
    isWin = false;
    ...        
}

public void Win (bool winGame)
{
    if (winGame)
    {
        isWin = true;
        winScreen.SetActive (true);
        target.GetComponentInChildren().enabled = false;
    }
}</pre></pre>
<pre>

Nun noch das WinTrigger.cs Skript erstellen.


using UnityEngine;
using System.Collections;

public class WinTrigger : MonoBehaviour {

    private CarGameManager gameManager;
    
    void Start ()
    {
        gameManager = GameObject.FindGameObjectWithTag ("GameController").GetComponent();
    }
    
    void OnTriggerEnter2D (Collider2D other)
    {
        if (other.gameObject.tag == "Car")
        {
            gameManager.Win (true);
        }
    }
}</pre>
<pre>

WinScreen_1

Jetzt habe ich schon mal ein kleines spielbares Game. Im nächsten Teil wird es um ein Start Up Screen und einer Spielerwahl gehen.

Bis dahin wünsche ich euch noch Happy Developing.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*