Unity 3. diel - Grafické rozhranie, pokročilý pohyb objektov

C# .NET Unity 3D Unity 3. diel - Grafické rozhranie, pokročilý pohyb objektov

Veľmi sa ospravedlňujem za obrovské oneskorenie, no mal som naozaj veľa práce s vlastnými hrami, zblol mi počítač, potom prišli letné prázdniny, dovolenky, potom škola a až teraz som si našiel čas na pokračovanie serálu o Unity. Chcel by som tiež vopred napísať, že v seriáli už ďalej nebudem opisovať všetky funcie ktoré Unity má, skôr sa budem venovať opisu ako spraviť do hry takú a takú vec. Všetko ostatné nádjdete ľahko cez Google.

Ale poďme k veci.

V tomoto dieli sa naučíme vytvoriť grafické rozhranie (GUI) a povieme si niečo o iných možnostiach ako hýbať s objektami. Scénu ani skripty z predošlého dielu ešte budeme potrebovať, nezmažte ich, ale vytvorte si novú scénu.

Ak vám niečo nebude fungovať, pozrite sa na spodok článku, bude tam zkopírovaný celý súbor.

GUI

Vytvorte nový skript s názvom GameGUI alebo niečo podobné (ale nie iba GUI, taký súbor už existuje!). Vytvorte kocku a pridajte do nej tento skript. Ok, začnime s niečim ľahkým.

OnGUI()

GUI elementy majú ve skripte lastnú funkciu: OnGUI(). Je to v podstate to isté ako Update (tiež sa zavolá každý frame), ale pre GUI. Dosť podstatná vec je, že všetky komponenty sa generujú každý frame znovu, keď generácíu prerušime (napr if-om), element prestane existovať.

Button (tlačidlo)

Pridajte toto do tela OnGUI:

if(GUI.Button(new Rect(5,10,70,25),"Reset"))
{
    transform.position = Vector3.zero;
    transform.rotation = Quaternion.identity;
}

Button použijeme ako bool do if-u. Ako 1. parameter použijeme new Rect(pozícia Y, pozícia X, šírka, výška). Ako 2. parameter použijeme hociaký string, v tomto prípade to bude "Reset" lebo bude slúžiť na reset pozície a rotácie.

Do tela IFu pridáme settery na poz. a rot. tak, aby obe nastavili na 0 (Vector3.zero = (0,0,0), Quaternion.identity = to isté pre rotáciu).

Kocku nejak natočte a posunte preč zo stredu.

Teraz spustite hru a mali by ste vidiet naše tlačidlo. Keď ho stlačíte, kocka by sa mala presunuť do stredu a natočiť naspeť na nulu. Ak vám to funguje, vypnite hru a kliknite pravým na transform v inspectori kocky a zvoľťe Reset, aby bola kocka zase na nule aj od začiatku hry.

Štrukturálne elementy

Aby to GUI aj nejak vyzeralo, máme na to pár vecí:

GUI.Box

Do OnGUI pridáme na začiatok GUI.Box(new Rect(0, 0, 100, 60), "Control"); Teraz uvidíme za tlačidlom okno s textom "Control".

Poradie komponentov v OnGUI je dôležité, podľa neho sa nám vytvoria aj na obrazovke - keby sme dali kód Boxu pod Button, na Button by sa v hre nedalo kliknúť, lebo by bol za boxom

GUI.Label

GUI.Label jednoducho vytvorí text na obrazovke. Použitie: GUI.Label(Rect, text). Zatiaľ nič nepridávajte, použijeme to už o chvíľu.

Window

Cez window vieme vytvoriť okno - zoskupiť viacero elementov. Do tela classy pridáme Rect window = new Rect(0,60,100,1­00); Do OnGUI pridáme window = GUI.Window(0, window, WindowFunction, "Rotation"); Parametre: unikátne ID okna, potom základový Rect okna, Funkcia okna a jeho text.

Na záver vytvoríme novú funkciu void WindowFunction(int id){ } Do tela tejto funkcie teraz môžeme pridávať GUI elementy. Window samo o sebe nemá veľmi veľký zmysel, ale ak na koniec funkcie pridáme GUI.DragWindow(new Rect(0, 0, 100, 100));, môžeme ho presúvať ťahaním (ak ho ale nedáte nakoniec, nastane zase problém s poradím)

Slidery

Pridáme si do tela classy premenú Vector3 rot = Vector3.zero; Potom prepíšeme v programe tlačítka transform.rotation = Quaternion.iden­tity; na rot = Vector3.zero. Tiež pridáme do Update() transform.rotation = Quaternion.Eu­ler(rot); Museli sme na Vector3 rot použiť funkciu Euler(), ktorá premení vector3 na quaternion (o tom nižšie).

Do WindowFunction pridáme:

GUI.Label(new Rect(5, 20, 9, 20), "X");
rot.x = GUI.HorizontalSlider(new Rect(15, 25, 75, 20), rot.x, 0, 360);
GUI.Label(new Rect(5, 40, 9, 20), "Y");
rot.y = GUI.HorizontalSlider(new Rect(15, 45, 75, 20), rot.y, 0, 360);
GUI.Label(new Rect(5, 60, 9, 20), "Z");
rot.z = GUI.HorizontalSlider(new Rect(15, 65, 75, 20), rot.z, 0, 360);

Vo funkcii GUI.Horizontal­Slider() je znovu Rect, potom jeho vlastná hodnota, potom minimálna a maximálna hodnota (všetko float). Použili sme tiež Label, pretože slider nemá sám o sebe nijaký text. Ak sa nad tým zamýslíte, mohlo vás napadnúť nastaviť rovno silderom transform.rota­tion.x, no nejde to. V Unity sa dá zmenit transform.rotation, ale nie transform.rota­tion.x/y/z (Dosť blbé). Skúste sa pohrať zo slidermi a tiež či stále funguje reset. Okno so slidermi môžete tiež posúvať. Okrem HorizontalSlider existuje logicky aj VerticalSlider.

Text

Na text máme 2 funkcie: TextArea(Rect,vlas­tná hodnota) a TextField(Rec­t,vlastná hodnota). Jediný rozdiel je v tom, že TextField podporuje viacriadkový text. Pridajte do tela classy Vector3 pos = Vector3.zero; a do update transform.position = pos;

Všetko vo WindowFunction sklopte do if (id == 0) { }

Do tela classy pridajte ešte

string x = "";
string y = "";
string z = "";

Ešte zmente v OnGUI transform.position = Vector3.zero; na pos = Vector3.zero; Teraz zopakujte proces s predošľým oknom: pridajte do tela funkcie Rect window2 = new Rect(0, 160, 100, 120); Do OnGUI() window2 = GUI.Window(1, window2, WindowFunction, "Movement"); a do WindowFunction pridajte if (id == 1) { }.

Na obe okná musíme použiť tú istú funkciu, preto musíme cez ifery zadať 2 odlišné operácie poďla ID okna.

Do tohto ifu pridajte:

GUI.Label(new Rect(5, 20, 9, 20), "X");
x = GUI.TextArea(new Rect(15, 20, 75, 20), x);
GUI.Label(new Rect(5, 40, 9, 20), "Y");
y = GUI.TextArea(new Rect(15, 40, 75, 20), y);
GUI.Label(new Rect(5, 60, 9, 20), "Z");
z = GUI.TextArea(new Rect(15, 60, 75, 20), z);

if (GUI.Button(new Rect(5, 85, 85, 25), "Move"))
{
    if (x == "") x = "0";
    if (y == "") y = "0";
    if (z == "") z = "0";
    pos = new Vector3(float.Parse(x), float.Parse(y), float.Parse(z));
}
GUI.DragWindow(new Rect(0, 0, 100, 120));

Snáď viete, čo to robí. Spustite hru a teraz môžete napísať do ďalšieho okna novú pozíciu a keď stlačíte Move, kocka sa tam teleportuje. Nepouživajte veľmi veľké čísla, lebo kocku neuvidíte (najlepšie medzi -2.0 - 2.0)

ScrollView

GUI elementy môžeme zoskupiť do ScrollViewu - oblasť cez ktorú môžeme scrollovať. Do tela classy pridajte Vector2 scrollPosition = Vector2.zero; Do OnGUI() pridajte:

scrollPosition = GUI.BeginScrollView(new Rect(0, 400, 100, 100), scrollPosition, new Rect(0, 400, 100, 200));
// rect viditeľnej časti SW, vlastná hodnota,  rect celého SW
GUI.Button(new Rect(0, 400, 100, 20), "Button1");  //obsah
GUI.Button(new Rect(0, 420, 100, 20), "Button3");
GUI.Button(new Rect(0, 440, 100, 20), "Button4");
GUI.Button(new Rect(0, 460, 100, 20), "Button5");

GUI.EndScrollView(); //koniec

Nevedel som vymislieť žiadne využite v aktuálnej scéne tak tie tlačítka nič nerobia :)

Toggle

Do tela classy pridajte bool toggle = false; A do OnGUI() toggle = GUI.Toggle(new Rect(0, 500, 100, 20), toggle, toggle.ToStrin­g()); Tiež to nič nerobí, ale ako text to ukazuje vlastnú hodnotu.

Toolbar

Do tela classy pridajte int toolbarInt = 0; a string[] toolbarStrings = { "0", "1", "2" }; Do OnGUI() pridajte ** toolbarInt = GUI.Toolbar(new Rect(0, 300, 100, 25), toolbarInt, toolbarStrings);** Parametre:rec­t,vlastná hodnota, pole obsahu (textu) tlačítok.

V GUI si ešte môžeme nasaviť vzhľad - GUIStyle alebo zmenit celé textúry(GUISkin), ale o tom možno niekedy nabudúce. :)

Lerp

Lerp je skratka pre Linear Interpolation. Je to matematická funkcia využívana napr. na lineárny pohyb objektov. Prepíšte v update zmenu pozície na transform.position = Vector3.Lerp (transform.po­sition, pos, 1 * Time.deltaTime);

Napísali sme tam súčasnú pozíciu, cieľovú pozíciu, rýchlosť * deltaTime - čo je trvanie 1 framu v in-game sekundách (ak nechápete, neriešte :) ) Vector3.Lerp lerpuje pozíciu, ale dá sa lerpovať aj float (Mathf.Lerp) a Quaternion (Quaternion.Sler­p/ Quaternion.Lerp).

Quaternion

V softvéri sa na rotáciu objektov často používa nie Vector3, ale Quaternion, ktorý ma okerm x,y,z aj w, čo udáva niečo ako silu rotácie, vysvetľovať by to bolo nadlho, ak vás to zaujíma, nájdete toho došt na youtube a googli.

Čo je podstatné je, že Quaternion vieme premeniť na Vector3 cez Quaternion.To­EulerAngles(Qu­aternion) a opačne cez Quaternion.Eu­ler(Vector3);

Ok nadnes stačilo. Nabudúce si vysvetlíme Input, kolízie a Raycast
Tu je screenshot, ako by GUI malo vyzerať a link k suboru online

GUI v Unity 3D

 

Stáhnout

Staženo 66x (2.84 kB)
Aplikace je včetně zdrojových kódů v jazyce C# .NET

 

  Aktivity (1)

Článek pro vás napsal DELTA12
Avatar
Autor sa venuje sa tvorbe hier v Unity a Unreal Engine, elektrotechnike, programovaniu AVR čipov a zriedkavo Windows Forms programom

Jak se ti líbí článek?
Celkem (2 hlasů) :
55555


 



 

 

Komentáře

Avatar
Ján Timoranský
Redaktor
Avatar
Ján Timoranský:

Pekný článok, som rád, že pokračuješ len neviem, či sa ti oplatilo rozoberať GUI, kedže už teraz je Unity beta 4.6, ktorá pridáva canvas a doňho všetko možné vrátane buttonov. Na druhej strane je ale pravda, že treba vedieť ako vytvoriť taký button aj pomocou scriptu. Každopádne držím palce v ďalšej tvorbe!! :)

Odpovědět 15.11.2014 23:11
Find what you love and let it kill you.
Avatar
DELTA12
Redaktor
Avatar
DELTA12:

Vdaka, ano, cez canvas sa da sice spravit staticke GUi, napr hlavne menu, ale dynamicke GUI sa da spravit iba cez skript pokial viem, napr ked robim nejaky in-game skaldackovy editor, tak musim vygenerovat tlacitko na spawn kazdeho mozneho komponentu, komponenty mozu byt pridane stale dalsie hocikedy a netreba v potom hre priamo nic menit.

Editováno 15.11.2014 23:17
 
Odpovědět 15.11.2014 23:16
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.