Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Unity (C#) Android: Generování stalagů, 2. část

V minulé lekci, Unity (C#) Android: Generování stalagů, jsme si vytvořili kolem mapy pohyblivý tunel, čímž jsme ji ohraničili, a vygenerovali si 50 stalagů.

Mapa má však stále ještě rezervy a proto budeme v generování pokračovat i v dnešním Unity 3D Android tutoriálu.

Různá výška překážek

Aby všechny překážky nebyly stejně velké, upravíme si metodu GenerateStalag() v našem StartScript do následující podoby:

void GenerateStalag(Vector2 p)
{
    GameObject g = Instantiate(stalagPrefab, p, Quaternion.identity) as GameObject;
    Vector3 scale = g.transform.localScale;

    scale.y = Random.Range(0.5f, 1.2f);

    g.transform.localScale = scale;
}

Za vysvětlení stojí řádek:

GameObject g = Instantiate(stalagPrefab, p, Quaternion.identity) as GameObject;

Kód funguje stejně jako předtím, jen s menším rozdílem. Náš vytvořený objekt se nám uloží do proměnné. S touto proměnnou následně můžeme pracovat a upravit libovolné vlastnosti nového objektu.

Vytvoříme si plně vybarvené okraje naší obrazovky, abychom tam neměli takovou díru. Výplň si přesuneme do objektu Borders1 a uložíme. Dotyčnou výplň vytvoříme s pomocí modrého obdélníku, který je ke stažení v minulé lekci. Stačí sprite přesunout na scénu a roztáhnout do požadované velikosti:

Tvorba 2D arkády pro Android v Unity

V Prefabu našeho stalagu si změníme Order in Layer na -1 a potvrdíme. To zajistí, aby se nám nepřekrýval s jinými sprity:

Tvorba 2D arkády pro Android v Unity

Aby naše hra byla lépe optimalizovaná, Prefabu našeho krápníku vytvoříme vlastní vrstvu. Pojmenujeme si ji StalagLayer a to samé uděláme s Prefabem zdi, které vytvoříme vrstvu BorderLayer:

Tvorba 2D arkády pro Android v Unity

Dále v Edit -> Project settings -> Physics2D nastavíme, aby spolu StalagLayer a BorderLayer nekolidovaly. To děláme proto, že na obou objektech máme collider a kdyby spolu tyto objekty neustále kolidovaly, mohla by se tím razantně zvýšit náročnost naší hry, která by se mohla následně sekat:

Tvorba 2D arkády pro Android v Unity

Stalagy ze země

Zatím nám překážka visí pouze ze stropu, zařídíme, aby trčela i ze země. To provedeme další změnou skriptu StartScript:

void Start()
{
    for (int i = 0; i < count; i++)
    {
        Vector2 pos = new Vector2();
        pos.x = offset + i * distance;

        int r = Random.Range(0, 2);
        int rotateIndicator = 1;
        if (r == 0)
        {
            pos.y = 4.5f; // může se lišit podle toho. jak máte vzdálený strop a podlahu od sebe
        }
        else
        {
            pos.y = -4.5f; // může lišit podle toho, jak máte vzdálený strop a podlahu od sebe
            rotateIndicator = -1;
        }

        GenerateStalag(pos, rotateIndicator);
    }
}

void GenerateStalag(Vector2 p, int rotateInd)
{
     GameObject g = Instantiate(stalagPrefab, p, Quaternion.identity) as GameObject;
     Vector3 scale = g.transform.localScale;

     scale.y = Random.Range(0.5f, 1.2f)  *rotateInd;
     g.transform.localScale = scale;
}

Když hru spustíme, můžeme vidět, že se nám stalagy náhodně otočily.

Optimalizace

Dále si hru trochu optimalizujeme. Teď generujeme všechny stalagy najednou, jenže to může být docela zbytečné. Tudíž jich budeme vždy generovat jen pár.

Na náš StartingObject si přidáme Box collider a odškrtneme, že se jedná o trigger. Zvětšíme a posuneme ho tak, aby byl na výšku přes celou naší hrací plochu a zároveň byl alespoň trochu široký. Následně ho přesuneme před hráče:

Tvorba 2D arkády pro Android v Unity

Dále hráči přidáme tag Player, který je v Unity již předvytvořený:

Tvorba 2D arkády pro Android v Unity

Tagy se objektům většinou přiřazují kvůli identifikaci. Není praktické rozeznávat objekty pomocí jména. Představte si situaci, kdy generujete hordy nepřátel, každý nepřítel s jiným jménem a máte jich stovky a chcete zjistit, jestli nějaký nepřítel například neudeřil hráče. Museli bychom zkontroloval všechna možná jména. Jednodušší způsob je všem nepřátelům přiřadit tag Enemy a jen zjišťovat, zda objekt s tagem Enemy udeřil hráče.

Dále si upravíme náš skript:

public GameObject stalagPrefab;
public float distance = 10;
public float offset = 10;
public int count = 50;

public Vector3 lastPos;

void Start()
{
    lastPos = transform.position;
    //GenerateSet(); // již nepotřebujeme ve startu
}

void GenerateSet()
{
    for (int i = 0; i < count; i++)
    {
        Vector2 pos = new Vector2();
        pos.x = lastPos.x + (2*distance) +  offset + i * distance;

        int r = Random.Range(0, 2);
        int rotateIndicator = 1;
        if (r == 0)
        {
            pos.y = 4.5f; // toto číslo se může lišit podle toho, jak máte vzdálený strop a podlahu od sebe
        }
        else
        {
            pos.y = -4.5f; // toto číslo se může lišit podle toho, jak máte vzdálený strop a podlahu od sebe
            rotateIndicator = -1;
        }

        GenerateStalag(pos, rotateIndicator);
    }
}

void GenerateStalag(Vector2 p, int rotateInd)
{
    GameObject g = Instantiate(stalagPrefab, p, Quaternion.identity) as GameObject;
    Vector3 scale = g.transform.localScale;


    scale.y = Random.Range(0.5f, 1.2f)  *rotateInd;

    g.transform.localScale = scale;
}

// vždy, když hráč proletí colliderem StartingObject, vygenerují se nové překážky a následně se náš celý objekt posune
void OnTriggerEnter2D(Collider2D col)
{
    if (col.CompareTag("Player"))
    {
        GenerateSet();
        lastPos = transform.position;
        lastPos.x += count * distance;
        transform.position = lastPos;
    }
}

Dále zajistíme, aby se naše překážky generovaly na správných místech. Stačí pouze lehce upravit naší metodu na generování:

void GenerateStalag(Vector2 p, int rotateInd)
{
    GameObject g = Instantiate(stalagPrefab, p, Quaternion.identity) as GameObject;
    Vector3 scale = g.transform.localScale;

    scale.y = Random.Range(0.5f, 1.2f)  *rotateInd;

    g.transform.localScale = scale;

    Bounds bound = g.GetComponent<SpriteRenderer>().bounds;
    p.y -= bound.size.y / 2 * rotateInd;

    g.transform.position = p;
}

Bounds jsou hranice (velikost) objektu. Vzali jsme si tedy velikost našeho spritu na stalagmit a vypočítali jsme díky tomu jejich umístění.

Když hru spustíme, můžeme vidět, že už vypadá pěkně.

Náhodná šířka a více druhů stalagů

Hráče může omrzet, když uvidí pouze jednu a tu samou překážku stále dokola, jen jinak velkou. Přidáme tedy i náhodnou šířku stalagů a dále i více druhů.

Více druhů stalagů

Abychom generovali více druhů stalagů, potřebujeme si vytvořit pole našich překážek:

public GameObject[] stalagPrefab;

Z naší proměnné pro Prefab vytvoříme pole. A následně musíme upravit ještě část kódu na generování:

GameObject g = Instantiate(stalagPrefab[Random.Range(0, stalagPrefab.Length)], p, Quaternion.identity) as GameObject;

Random.Range(0, stalagPrefab.Length) nám zajistí vygenerování stalagmitu na náhodném indexu z celé délky pole našich stalagmitů.

Teď, když se podíváme do Inspectoru na náš StartingObject, můžeme tam vidět možnost zvolit velikost našeho pole. My zvolíme 4:

Tvorba 2D arkády pro Android v Unity

Můžete použít sprity, které jsem vám dal ke stažení a nebo si můžete vytvořit vlastní:

Tvorba 2D arkády pro Android v Unity

Následně uděláme to samé jako s prvním stalagem. Nastavíme barvu, collider, order in layer, Layer a uložíme jako Prefab. Následně tento Prefab přetáhneme v Inspectoru do pole Stalag Prefab:

Tvorba 2D arkády pro Android v Unity

Když hru spustíme, můžeme vidět, že se generují různé druhy.

Takto si můžeme vytvořit libovolný počet různých stalagů. Pokud nám budou připadat velké a nebo malé, můžeme si velikost generování libovolně upravit.

Pro lepší přehlednost si vytvoříme další proměnné:

public float minHeight;
public float maxHeight;
public float minWidth;
public float maxWidth;

Ve finále si upravíme naší metodu na generování, aby se náhodně určovala i šířka stalagů:

scale.y = Random.Range(minHeight, maxHeight)  *rotateInd;
scale.x = Random.Range(minWidth, maxWidth);

Od teď můžeme pohodlně z Inspectoru měnit naše hodnoty a nemusíme pracně hledat v kódu. Hodnoty nastavíme následně:

Tvorba 2D arkády pro Android v Unity

Pokud se nám někdy bude zdát, že hodnoty potřebují upravit, uděláme to z tohoto místa.

Závěr

Pro dnešek to bude vše. Doufám, že se vám série tutoriálů líbí a naučili jste se něco nového. Pokud máte nějaké připomínky či nápady, zanechte komentář, rád se inspiruji.

Příště se v lekci Unity (C#) Android: GUI - Menu 1 podíváme na vytvoření menu.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 390x (92.84 kB)

 

Předchozí článek
Unity (C#) Android: Generování stalagů
Všechny články v sekci
Tvorba 2D arkády pro Android v Unity
Přeskočit článek
(nedoporučujeme)
Unity (C#) Android: GUI - Menu 1
Článek pro vás napsal Jan Kubice
Avatar
Uživatelské hodnocení:
4 hlasů
Aktivity