IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

10. diel - Unity (C #) Android: Štart, Skóre, PlayerPrefs

V minulej lekcii, Unity (C #) Android: Prestavba, bodáky , sme upravili pohyb hráčov a pozmenili aj spôsob, akým sa nám posúvajú prekážky.

Dnes sa pozrieme na počítač skóre a tiež na počkanie na štarte, kým hráč nekliknete, aby mal čas sa na hru plne pripraviť.

Čakania na štart

Začneme s vyčkaním, kým hráč nezačne hrať. Pre tento účel upravíme skript pre pohyb hráčov. Najprv ale objektu Player nastavíme gravitáciu na 0, aby nám pri čakaní nepadal. Ideálne si číslo, ktoré ste mali nastavené predtým, niekam poznačte.

Teraz si otvoríme PlayerMoveScript.

Do nášho skriptu si pridáme na úplný začiatok novú premennú:

bool started = false;

A do Update() metódy vložíme nasledujúci kód:

if (!started)
{
    return;
}

Keď hru spustíme, hráč nám stojí na mieste a nehýbe sa. To je presne to, čo sme chceli. Avšak v tento moment chceme čakať, kým hráč nezačne hrať. Predtým, než budeme reagovať na nejakú tú akciu, si vytvoríme metódu v tom istom skriptu. Metóda sa bude volať StartGame():

void StartGame()
{
    started = true;
    rigidbody2D.gravityScale = 1f; // Vaše hodnota, např. 1f

    Vector3 vel = rigidbody2D.velocity;
    vel = Flap(vel);

    rigidbody2D.velocity = vel;
}

Metóda nám pri jej zavolanie nastaví started na true. Tiež nastaví gravitáciu na pôvodné číslo, ktoré sme mali nastavené na hráčovej (to si v kóde upravte).

Keď hráč klikne, začne padať a musel by rýchlo klepnúť znova. Preto sme zariadili, aby nám postavička zároveň aj "flapla" a tým hráč dostane chvíľu času na zareagovaní. Používame k tomu metódu Flap(), ktorú si hneď tiež pridáme.

Kód metódy Flap() je nasledovné:

Vector3 Flap(Vector3 v)
{
        v.y = flapAmount;
        return v;
}

Teraz upravíme časť pod podmienkou !started do tejto podoby:

if (!started)
{
    if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
    {
        StartGame();
    }

    return;
}

Keby sa niekomu nepodarilo poskladať metódy do skriptu, nižšie je pre kontrolu jeho finálna podoba:

float flapAmount = 7;
float speed = 5;
bool started = false;

void Start()
{

}

// Update is called once per frame
void Update()
{

    if (!started)
    {
        if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
        {
            StartGame();
        }

        return;
    }


    Vector3 vel = gameObject.GetComponent<Rigidbody2D>().velocity;

    if (Input.GetMouseButtonDown(0))
    {
        vel = Flap(vel);
    }

    vel.x = speed;

    gameObject.GetComponent<Rigidbody2D>().velocity = vel;

}

void StartGame()
{
    started = true;
    GetComponent<Rigidbody2D>().gravityScale = 1f;

    Vector3 vel = GetComponent<Rigidbody2D>().velocity;
    vel = Flap(vel);

    GetComponent<Rigidbody2D>().velocity = vel;
}

Vector3 Flap(Vector3 v)
{
    v.y = flapAmount;
    return v;
}

Nie je tu asi nič, čo by sme museli špeciálne vysvetľovať. Všetko v tomto kóde už v tutoriálu zaznelo, tak sa môžeme vrhnúť na ďalšiu časť.

Počítanie skóre

Teraz začneme s počítaním skóre. Na náš Stalag pridáme ďalší objekt, ktorý bude zisťovať, či hráč preletel. Všetkým prefabům Stalag pridáme objekt. Vytvoríme si prázdny gameObject, vynulujeme jeho súradnice a pomenujeme ho napríklad stalagScore. Tento objekt vložíme ako podobjektoch Stalag. Pridáme mu Box Collider2D.

Collider si zväčšíme po osi Y dostatočne ďaleko a pokúsime sa Collider narovnať sa spodkom Stalag. Alebo ho tiež môžeme dať viac do stredu, čo sa vám viac páči, na funkcionalitu to vplyv mať nebude. Nebojte sa to vážne roztiahnuť pokojne na desaťnásobok veľkosti Stalag. Mohlo by sa stať, že tento Collider bude moc malinký kvôli našom generovanie Stalag v náhodných veľkostiach a hráč sa ho treba ani nedotkne a nebudú pripisovať sa mu skóre. Tiež musíme tento Collider nastaviť ako trigger:

Tvorba 2D arkády pre Android v Unity

Ďalej tomuto objektu pridáme ScoreScript. Tento skript bude, ako si tušíte, pripísať skóre. Pre tieto účely si pridáme Text na obrazovku ako GameObject -> UI -> Text.

Vytvorí sa nám samozrejme tiež Canvas, ale s tým už vieme pracovať z minulých lekcií. Teda si ho nastavíme na kameru, aby bol stále pekne vidieť. Tento text nám bude vypisovať aktuálne skóre. Text si umiestnime do pravého horného rohu, zväčšíme si font a text nastavíme napríklad len na Score: 0. Tomuto textu pridáme TextScoreScript.

Základ máme pripravený.

Skripty

Vrhneme sa na ony dva skripty.

TextScoreScript

Najskôr upravíme náš TextScoreScript:

static int score = 0;

void Start ()
{
    score = 0;
}

public static void AddScore()
{
    score++;
}

Programátori určite tuší, prečo pred score máme static int. Neprogramátori asi veľa nevie. Keď máme nejakú statickú premennú alebo metódu, sme schopní k nej pristupovať aj z rôznych metód a tried, bez toho aby sme ju museli nejako získavať. Takáto metóda však ale môže pracovať zas len so statickými premennými v triede. Vďaka tomu, že metódu máme statickú, sme schopní urobiť ďalší skript jednoduchšie.

ScoreScript

Keď cez náš trigger preletí hráč, chceme pripísať skóre. To urobíme zavolaním metódy na triede ScoreScript:

void OnTriggerEnter2D(Collider2D col)
{
    if(col.CompareTag("Player"))
    {
        print("Adding score");
        ScoreScript.AddScore();
    }
}

Vďaka tomu, že v danej triede máme metódu statickú, sme schopní k nej pristúpiť, bez toho aby sme robili niečo takéto:

GameObject.Find("název objektu").SendMessage...

Alebo ešte horšie takého:

GameObject.Find("název objektu").getComponent...

Horšie preto, že je to zbytočne zložité, ako pre nás, tak pre počítač. Predstavte si scénu, kde máte tisíce objektov a počítač medzi nimi musí nájsť daný objekt, na objekte nájsť skript a až potom sme tam, kde chceme byť.

Teraz, keď hráč preletí úspešne okolo Stalag, vnútorne sa nám skóre pripočíta, ale nikde ho nevidíme.

TextScoreScript

Preto sa vrátime späť do TextScoreScript, kde zavedieme novú premennú. Pokiaľ hráč zdolá prekážku, túto premennú si nastavíme na true a zmeníme text, ktorý ukazuje aktuálny body:

static int score = 0;
static bool changed = false;

void Start ()
{
    score = 0;
}

void Update ()
{

    if(changed)
    {
        changed = false;
        gameObject.GetComponent<Text>().text = "Score: " + score;
    }

}

public static void AddScore()
{
    score++;
    changed = true;
}

Pri aktualizovanie texte sa vždy odkážeme na aktuálny objekt, kde sa nachádza náš text na vypisovanie skóre, a zároveň náš skript.

Pripočítania skóre hotové a my sa môžeme vrhnúť na ukladanie najlepšieho skóre.

Najlepšie skóre

Pridáme si nový text, ktorý si dáme menšiu než ten pôvodný, a pomenujeme si ho GUIHighScore. Dáme text pod naše aktuálne skóre. Tiež mu môžeme pridať text highscore::

Tvorba 2D arkády pre Android v Unity

Tomuto textu pridáme nový skript HighScoreScript. Najskôr sa ale vrátime k nášmu ScoreScript.

ScoreScript

Pridáme si do neho jednu metódu:

void OnDestroy()
{
    int highscore = PlayerPrefs.GetInt("highscore", 0);

    if (score > highscore)
        PlayerPrefs.SetInt("highscore", score);
}

Táto metóda je v Unity už predpripravená podobne, ako sú metódy Start() alebo Update(). Táto metóda sa volá vždy pri zničení objektu alebo pri ukončení scény.

PlayerPrefs

Ďalej tu máme PlayerPrefs. To je trieda s užitočnými metódami pre ukladanie veľmi jednoduchých dát.

Načítanie

Dáta hráča načítame takto:

PlayerPrefs.GetInt("highscore", 0);

Načítame hodnotu, ktorá je uložená pod kľúčom "highscore". Ak daná hodnota nebude nájdená, uloží sa nám do premennej 0. Keby sme ako druhý parameter zadali napríklad 5, tak budeme mať v highscore hodnotu 5, ak sa žiadne uložené skóre nenájde.

Ukladanie

Metóda SetInt() robí presný opak:

PlayerPrefs.SetInt("highscore", score);

Ukladáme pod kľúč "highscore" číslo, ktoré sa nachádza v premennej score:

Takže ak hráč dosiahne skóre väčšieho, než je uložené v PlayerPrefs, tak sa zapíše do pamäti.

Ak by vás zaujímalo, kam sa napríklad na Windows tieto hodnoty ukladajú, môžete ich nájsť uložené v registroch. Samozrejme je tam nájdete až aspoň po jednom odohraní hry. Pre neskúsených odporúčam sa v registroch počítača moc nehrabú, môžete si nepríjemne poškodiť súbory a funkčnosť aplikácií.

Na účely testovania hry si môžeme pridať na prvý riadku metódy OnDestroy() vymazanie skóre:

PlayerPrefs.DeleteKey("highscore");

To zaistí, aby sme zbytočne nenahrali veľké skóre na našom počítači. Až hru budeme mať hotovú, nezabudnime túto riadku samozrejme zmazať.

Ešte jedna možnosť je tá, že si môžeme pridať podmienku:

If (Application.isEditor)
    PlayerPrefs.DeleteKey("highscore");

Takže kým nebudeme mať hru vydanú a budeme ju spúšťať iba cez Unity, tak sa zakaždým vymaže skóre.

HighScoreScript

Teraz sa presunieme do HighScoreScript:

void Start ()
{
    int highscore = PlayerPrefs.GetInt("highscore", 0);
    gameObject.GetComponent<Text>().text = "Highscore: " + highscore;
}

Takže zakaždým, keď hru spustíme, sa nám aktualizuje text obsahujúci highscore na najvyššie nahrané skóre.


 

Predchádzajúci článok
Unity (C #) Android: Prestavba, bodáky
Všetky články v sekcii
Tvorba 2D arkády pre Android v Unity
Preskočiť článok
(neodporúčame)
Unity (C #) Android: MenuPart, Eraser, pozadia
Článok pre vás napísal Jan Kubice
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity