06. Prvý skript

Prišiel čas začať písať vlastné skripty, lebo Unity za nás neurobí všetko. Začneme ale veľmi zľahka. Pre začiatok vytvoríme skript, ktorý oživí našu scénu otáčacími prekážkami.

Nič si nerobte, ak nebudete v tejto lekcii rozumieť tomu, čo robíme. Na programovanie sa neskôr pozrieme systematickejšie. Dnes si len tak letmo ohmatáme jeden skript.

Doteraz sme skripty sťahovali už hotové a pridávali sme ich na game objekty. Vytvorme teraz nový asset typu C# script v adresári Scripts a nazvime ho Rotator:

Pri poklikaní na tento asset sa otvorí editor kódu (Visual Studio Community) a v ňom vidíme nový prázdny skript v súbore Rotator.cs:

On teda nevyzerá úplne prázdny, už je v ňom kdečo napísané. Je to kostra skriptu, ktorú za nás vyrobilo Unity samo. Nemusíme v tejto chvíli rozumieť všetkému a ani nebudeme v skripte vŕtať, kam netreba. Podstatné sú pre nás teraz dve časti:

Start( ) a Update( )

Start aj Update sú tzv. metódy. Do nich budeme písať príkazy, ktoré chceme aby Unity vykonalo. Zatiaľ sú obidve metódy prázdne, nič neobsahujú a nič nerobia. Preto som aj povedal, že tento skript je prázdny.

Metóda Start sa vykoná vždy vtedy, keď na scéne pribudne game objekt, ktorý na sebe nesie tento skript.

Metóda Update sa vykonáva neustále dokola. Presnejšie, vykonáva sa vždy pred vykreslením ďalšieho snímku.

Tak ako film pozostáva z filmových políčok, aj videohra sa na obrazovku vykresľuje ako rýchla sekvencia po sebe idúcich obrázkových políčok – frameov. Skôr ako sa nejaký frame vykreslí na obrazovku, musí počítač prepočítať kam sa ktorý objekt pohol, čo sa ako zmenilo a tak podobne. A to je chvíľa, kedy sa vykonáva metóda Update.

Základné pravidlo je, že:

  • Ak chceme, aby sa niečo vykonalo raz na začiatku, napíšeme to do Start.
  • Ak chceme, aby sa niečo vykonávalo stále, napíšeme to do Update.

Sú aj metódy, ktoré sa vykonajú, keď sa nejaké objekty dotknú, alebo keď napríklad niečo vojde do triggeru. O tom ale inokedy.

Moj prvý príkaz

My chceme, aby sa žltí pandrláci otáčali neustále, takže budeme písať do Update. A teraz, čo tam napíšeme.

Geometrické transformácie ako posúvanie, otáčanie, škálovanie sme v inšpektore klikali do komponentu Transform. V skripte má tento komponent špeciálne postavenie a volá sa tu transform. Tento komponent pozná každý skript (lebo každý game objekt má komponent Transform). Iné komponenty nemajú takéto privilégium.

No a tomuto transformu prikážeme, aby zrotoval. Konkrétne takto:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotator : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.Rotate(0, 2, 0);
    }
}

Rozoberieme si, čo sa v tomto príkaze deje:

        transform.Rotate(0, 2, 0);
  • transform je komu prikazujeme
  • Rotate je čo prikazujeme
  • (0, 2, 0) sú tzv. parametre. V našom prípade sú to uhly otočenia okolo osí x,y,z, čiže chceme, aby sa game objekt otočil o 0 stupňov okolo x, 2 stupne okolo y a 0 stupňov okolo z.

Nateraz je náš skript hotový. Uložte súbor Rotator.cs a vráťte sa z editoru kódu naspäť do Unity.

Priraďte skript Rotator na prefab Prekazka.

Keď teraz spustíme hru, prekážky sa rotujú, hurá. Ak náhodou nie, pozrite sa do konzoly, či sa tam nedeje nejaká chyba a skontrolujte si, či máte správne zapísaný príkaz na rotáciu. Vrátane veľkých a malých písmen.

Vyskúšajte v kóde zmeniť parametre rotácie (0, 2, 0) na iné hodnoty a sledujte, čo sa deje. Nezabudnite vždy uložiť skript v editore kódu a nanovo spustiť hru v Unity, inak sa zmena neprejaví.

Moja prvá vlastnosť skriptu

Asi ste si všimli, že zmena parametra v príkaze Rotate mení rýchlosť rotácie. Prípadne ak meníme aj parametre rotácie okolo x a z (pôvodne to sme tam mali nuly), tak sa mení aj smer rotácie.

Je ale trochu otrava pri nastavovaní rýchlosti rotácie vždy editovať skript. Navyše, čo by sme robili, keby sme napríklad chceli, aby sa každá prekážka rotovala inou rýchlosťou? Veď skript je iba jeden. Oba tieto problémy vyriešime cez tzv. vlastnosť skriptu.

Pozrime sa najprv v Unity ako vyzerá na prefabe Prekazka náš komponent Rotator:

Tento komponent zatiaľ nemá žiadne nastavenia – vlastnosti. V iných komponentoch rôzne vlastnosti sú. Komponentu Audio Source sme nastavovali aký zvuk má prehrať. Komponentu Generator na game objekte Generator sme nastavovali čo má generovať. A podobne. Tu v komponente Rotator by sa nám hodilo mať vlastnosť pre nastavenie rýchlosti. Poďme si ju vyrobiť. Šup do editora skriptu…

Pridajme do skriptu riadok public float speed; Aha takto sem:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotator : MonoBehaviour
{
    public float speed;

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.Rotate(0, 2, 0);
    }
}

Zatiaľ si nebudeme vysvetľovať, čo tento pridaný riadok znamená. Podstatné je, že keď uložíme takto upravený skript, objaví sa v komponente Rotator vlastnosť „Speed„:

Tu budeme môcť meniť rýchlosť otáčania.

Nastavte v inšpektore Speed na 5

Spustite hru a sledujte, čo sa zmenilo. Nič. Lebo síce sme pridali skriptu novú vlastnosť speed, ale v príkaze na rotovanie nám stále svieti číslo 2:

        transform.Rotate(0, 2, 0);

Preto namiesto dvojky teraz použijeme vlastnosť speed:

        transform.Rotate(0, speed, 0);

Uložte skript a spustite hru. Vygenerované prekážky sa teraz už točia takou rýchlosťou, akú majú nastavenú v komponente Rotator. Odteraz už nemusíme pre zmenu rýchlosti rotácie prepisovať nič v kóde.

A keď chceme, môžeme počas behu spustenej hry pomeniť jednotlivým vygenerovaným prekážkam cez ich inšpektor rýchlosť. Každej nejakú inú:

Moja prvá náhoda

A aby sme nemuseli nastavovať manuálne rôzne rýchlosti. doplníme do skriptu ešte jeden príkaz. Na začiatku nastavíme rýchlosť otáčania na náhodnú hodnotu.

Keďže chceme, aby sa nastavenie rýchlosti vykonalo iba raz na začiatku a nie aby sa rýchlosť menila znova a znova v každom snímku, budeme písať do metódy Start. Konkrétne toto:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotator : MonoBehaviour
{
    public float speed;

    // Start is called before the first frame update
    void Start()
    {
        speed = Random.Range(0, 5);
    }

    // Update is called once per frame
    void Update()
    {
        transform.Rotate(0, speed, 0);
    }
}

Tento príkaz nastaví hodnotu vlastnosti speed na náhodné celé číslo v rozsahu 0,1,2,3,4. (Prečo nie aj 5, o tom inokedy). Uložte skript a vyskúšajte spustiť hru. Žltí panáci sa otáčajú každý inak. Niektorí sa možno neotáčajú vôbec, to sú tí, ktorým náhoda vygenerovala nulu.

Skúste zmeniť v skripte parametre náhodného generovania z (0, 5) na (-5, 5). Niektoré prekážky dostanú náhodou aj zápornú rýchlosť otáčania, čo spôsobí, že sa budú otáčať v opačnom smere.

Možno sa vám v Unity deje taká vec, že ak sa v hre nepohybujete, točia sa prekážky rýchlejšie ako keď sa pohybujete. Nič nie je pokazené. To len sme napísali skript trošku nevhodne. V budúcnosti sa k tomu vrátime a prepíšeme ho tak, aby bol dokonalý. Zatiaľ to neriešime.

Zhrnutie

  • Skript v Unity má vlastnosti a metódy. My sme napríklad vytvorili vlastnosť speed a použili sme metódy Start a Update.
  • Metóda Start sa vykonáva iba raz – keď sa game objekt nesúci tento skript objaví na scéne.
  • Metóda Update sa vykonáva neustále, vždy pred vykreslením nového snímku.

Ničomu viac zatiaľ nemusíte rozumieť. V ďalších lekciách na chvíľu opustíme náš projekt a urobíme si rýchlokurz programovania.

Pokračujte na kurz Programovanie v Unity

Hotový projekt po tejto lekcii: MojaHra_06.zip