Vianoce v ITnetwork sú tu! Dobí si teraz kredity a získaj až 80 % extra kreditov na e-learningové kurzy ZADARMO. Zisti viac.
Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.

8. diel - 3D strieľačka v Unity - Streľba na nepriateľa

V minulej lekcii, 3D strieľačka v Unity - Efekty streľby , sme si urobili efekt streľby, zvuk výstrelu a pridali si mieridlá.

V dnešnej lekcii budeme programovať streľbu. Keď stlačíme ľavé tlačidlo, tak sa nám spustí animácia výstrelu a zároveň sa posunie objekt, na ktorý mierime, v smere nášho výstrelu. Všetko bude vyzerať nejako takto:

Tvorba 3D hier v Unity

Spôsoby implementácie streľby

Streľba sa v Unity 3D sa dá implementovať mnohými spôsobmi. Poďme si predstaviť tie najzákladnejšie a vybrať pre nás ten najlepší.

Guľka sa skriptom

Ako príklad si uveďme možnosť vytvoriť ( "spawnout") guľku po stlačení ľavého tlačidla myši. Táto guľka by mala na sebe prichytený skript, ktorý by ju okamžite po vzniku pridával silu v smere, ktorým je namierená. Táto možnosť je zložitejšia a komplexnejšia pre našu hru. Pracuje sa v nej veľa s rotáciami objektu a získavaním smere.

Raycast

Druhá možnosť, ktorú Unity 3D ponúka a je často využívaná, je urobiť si polpriamku, ktorá vychádza zo zbrane a mieri na miesto, kam sa hráč pozerá:

Tvorba 3D hier v Unity
Užíva sa k tomu metóda Raycast(), ktorú by sme mohli do slovenčiny preložiť ako "vyšli lúč" alebo "vyšli polpriamku". Táto metóda má mnoho parametrov a nachádza sa v triede Physics. My zadáme iba tri parametre:

  • pozície, odkiaľ má vychádzať naše polpriamka
  • smer - už sme si povedali, že bude smerovať na miesto, kam mierime. Tento smer je rovnaký ako smer, ktorým sa pozeráme. Alebo ak rovnaký smer, aký má naša kamera. A ako získať smer, ktorým "sa pozerá" naša kamera? Pomocou objekt.transform.forward, kedy objekt tu bude naša kamera.
  • naše premenná, do ktorej sa budú ukladať informácie o objekte, ktorý naše polpriamka trafí. Táto premenná je typu RaycastHit.

Teraz sa môžeme vrhnúť na reálne činy, keď už vieme ako to funguje a čo potrebujeme urobiť.

Príprava na programovanie

Najskôr potrebujeme na niečo strieľať. Vytvoríme si nový objekt Cube a prichytíme na neho komponent Rigidbody. Vďaka tomu ju potom môžeme pridať silu v smere nášho výstrelu a na objekt sa budú aplikovať fyzikálne zákony.

Najskôr zo všetkého kliknite pravým tlačidlom niekde na voľnú oblasť v záložke Hiearchy, po rozrolovanie ponuky zvolíme možnosť 3D Object a potom možnosť Cube. Novovzniknutý objekt si môžete pomenovať akokoľvek, názov nebude mať žiadny vplyv na náš kód:

Tvorba 3D hier v Unity

Ja som si svoju kocku pomenoval Target. Teraz klikneme na kocku ľavým tlačidlom a pozrieme sa do záložky Inspector. Tu klikneme na tlačidlo Add Component, napíšeme Rigidbody a klikneme na Rigidbody vo výsledkoch vyhľadávania.

Pozor, nevyberiete omylom Rigidbody2D, ktoré je určené pre 2D hry ! Inak vám pohyb nebude fungovať.

Klikneme ľavým tlačidlom na záložku Transform a vložíme súradnice, napr: 5, 1, 5 alebo aké si vy sami zvolíte, aby bola kocka niekde príhodne umiestnená:

Tvorba 3D hier v Unity

V novo pridané komponente Rigidbody nemeňte žiadne hodnoty. Ak si s tým budete chcieť pohrať, tak odporúčam až po tvorbe nášho skriptu pre streľbu. Jednotlivé kolónky v tejto komponente ako napríklad Mass alebo ak hmotnosť ovplyvní, aký bude mať vplyv náš výstrel na tento objekt.

Posledné, čo nám zostáva, je upraviť vzor objektu, ktorý budeme vytvárať vždy po výstrele. Tento objekt nám bude tvoriť efekt zásahu. Efekt je už hotový a máme ho importovaná spolu so všetkými vecami z nášho balíka. Stačí kliknúť ľavým tlačidlom myši na priečinok Low Poly F ... v záložke Project, potom kliknúť na Prefabs -> Example_P ... -> Bullet_Imp ... a tu dvakrát kliknúť na súbor Metal Imp ..., čo je úder na kov.

Vedľa objektu Metal Impact Prefab klikneme na sipecka a tým rozroluje podobjektoch. Vyberieme podobjektoch Metal Bullet Hole Particle a deaktivujeme celý podobjektoch kliknutím na štvorček vedľa názvu. To preto, že keď by sme podobjektoch nechali aktívne, po výstrele by sa nám objavil nepekný model "diery po výstrele" v objekte. Nám stačí mať tu len aktivovaný prvý podobjektoch, ktorý zaisťuje iskry a zvuk zásahu. Schválne si môžete nechať podobjektoch aktívny obaja a rozhodnúť sa, či sa vám efekt páči a alebo nie:

Tvorba 3D hier v Unity

Skript EnemyHealth

Teraz nášmu objektu Target pridáme ešte nový skript EnemyHealth, ktorý bude na každom našom kedy vytvorenom nepriateľovi. Tento skript bude zisťovať koľko má daný nepriateľ, na ktorom je náš skript, životov a ak bude mať nulu, tak sa ten daný objekt zničí.

Ľavým tlačidlom klikneme na objekt Target a pozrieme sa do záložky Inspector. Tu klikneme na tlačidlo Add Component a vpíšeme názov nášho skriptu EnemyHealth. Klikneme na tlačidlo New Script a potom už len na Create and Add a skript je pridaný.

Skript shoot

Ľavým tlačidlom klikneme na náš objekt s názvom Assault_Rifle_01_FPSController. Potom v záložke Inspector klikneme na tlačidlo Add Component a napíšeme shoot. Klikneme na tlačidlo New Script potom už len na Create and Add a máte hotovo:

Tvorba 3D hier v Unity

Následne už len dvakrát klikneme na náš skript shoot a tým ho otvoríme.

Kód

Obsah skriptu bude nasledujúci:

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

public class shoot : MonoBehaviour
{
    RaycastHit hitInfo;
    Animator objectwithAnim;
    public float dostrel;
    public float sila;
    public float poskozeni;
    public GameObject efekttrefy;
    void Start()
    {
        objectwithAnim = GameObject.FindGameObjectWithTag("Animobject").GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0)&&!objectwithAnim.GetBool("Run") && !objectwithAnim.GetBool("Holster") && !objectwithAnim.GetCurrentAnimatorStateInfo(0).IsName("Inspect")) // pokud stiskneme levé tlačítko, neběžíme, nemáme schovanou zbraň a ani není spuštěna animace prohlížení
        {
            InvokeRepeating("Shoot", 0, 0.25f); // opakuje metodu Shoot(), začíná okamžitě bez prodlevy, opakuje se každých 0.25 sekundy
        }
        if (Input.GetMouseButtonUp(0))
        {
            CancelInvoke("Shoot"); // přestává se volat metoda Shoot()
        }
    }
    void Shoot() // námi nově vytvořená metoda
    {
        if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hitInfo, dostrel)) // pokud něco trefíme, parametry jsou: místo, odkud půjde polopřímka, směr, kam má ukládat informace o tom, co se zasáhlo, a dálka, kam až povede.
        {
            GameObject trefa= Instantiate(efekttrefy,hitInfo.point, Quaternion.LookRotation(hitInfo.normal));
            Destroy(trefa, 1);
            if (hitInfo.transform.GetComponent<Rigidbody>()) // pokud objekt, který jsme trefili, má komponentu Rigidbody
            {
                hitInfo.transform.GetComponent<Rigidbody>().AddForce(Camera.main.transform.forward * sila); // přidáme sílu ve směru, kterým se díváme
            }
            if (hitInfo.transform.GetComponent<EnemyHealth>()) // pokud objekt, který jsme trefili, má komponentu EnemyHealth
            {
                hitInfo.transform.GetComponent<EnemyHealth>().GetDammage(poskozeni); // spouštíme metodu v jiném skriptu, parametrem jsme si nastavili množství poškození
            }
        }
    }
}

Kód je okomentovaný, prejdite si ho. Opäť tu máme niekoľko vecí k podrobnejšiemu vysvetlenie.

RaycastHit.normal

normal je premenná typu Vector3. Objekt, keby bol kolmý k tomu, čo sme pomocou neviditeľnej polpriamky ray trafili, by mal smer rovnaký ako je hodnota premennej normal (je to teda zvislej polohy). Nasledujúci obrázok by vám to mal pomôcť pochopiť:

Tvorba 3D hier v Unity
Túto premennú má každá polpriamka ray. LookRotation() nám vráti hodnotu vo forme Quarterion (rotácie), ktorú by sa tým smerom daný objekt pozeral.

Skript EnemyHealth

Uveďme si aj druhý skript:

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

public class EnemyHealth : MonoBehaviour
{
    // Start is called before the first frame update
    public float zivoty;
    void Start()
    {

    }

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

    }
    public void GetDammage(float poskozeni) // nová metoda musí být public, abychom ji mohli zavolat z jiného skriptu
    {
        zivoty -= poskozeni; // odečte jednorázově poškození od životů
        if (zivoty <= 0)
        {
            Destroy(transform.gameObject); // metoda, která ničí herní objekty, jako parametr můžete nastavit čas od zavolání této metody, než se zničí
        }
    }
}

Inicializácia public premenných v Unity Editore

Teraz, keď sme si vytvorili kód, ktorý nám všetko riadi, nastavíme ešte hodnoty jednotlivým public premenným. U nášho nepriateľa je to hodnota životov au nášho skriptu pre streľbu to sú:

  • dostrel zbrane
  • sila, ktorá pôsobí na nepriateľa
  • vzor efektu
  • poškodenie, ktoré mu udelí

Premenné skriptu shoot

Klikneme ľavým tlačidlom na objekt Assault_Rifle_01_FPSController. V záložke Inspector sa nám zobrazí všetko, čo je na tomto objekte prichytené za komponenty. Nás zaujíma komponenta shoot, ktorá je náš skript. Tu vidíme štyri od seba oddelená políčka s názvami: dostrel, Sila, poškodený, Efekttrefy. Táto políčka predstavujú rovnomennej premenné v našom skriptu. Podľa toho, aké im nastavili hodnoty, sa hra bude správať. Keď nastavíte premennú Silá na 5000, tak nám objekt, na ktorý vystrelíte a má Rigidbody, odletí zo zorného poľa:

Tvorba 3D hier v Unity

Ja som zvolil hodnoty:

  • Dostrel: 20,
  • Silá: 100,
  • Poškodené: 20.

Pre premennú Effekttrefy musíme zvoliť náš skôr upravený objekt v ktorom máme efekty. Ako prvý ho nájdeme opäť v záložke Project. Potom ho myšou pretiahneme do voľného poľa s nápisom None (Game Object) vedľa názvu Efekttrefy. Tým sa nám herné objekt priradí do tejto premennej.

Druhý spôsob je kliknúť na koliesko vo voľnom poli s nápisom None (Game Object) a napísať do vyhľadávacieho okienka, ktoré nám vyskočí: Metal Impact Prefab a potom na vyhľadaný objekt kliknúť ľavým tlačidlom.

Premenné skriptu EnemyHealth

Klikneme ľavým tlačidlom na nášho nepriateľa, v mojom prípade pomenovaného Target. V záložke Inspector následne uvidíme náš skript, ktorý je na našom nepriateľovi prichytený. Skript sa volá EnemyHealth. Skript by mal mať viditeľnú premennú život. Tento ukazovateľ, ako ste už pochopili, určuje nepriateľovho zdravie. Čím vyššia hodnota, tým viac výstrelov vydrží. Ja mám nastavenú hodnotu 100:

Tvorba 3D hier v Unity

Skúška strieľanie

Teraz máme všetko nastavené a môžeme spustiť hru:

Tvorba 3D hier v Unity

Skúste si schválne meniť hodnoty u komponenty Rigidbody prichytené na našom nepriateľovi a sledujte, čo sa bude diať:)

V ďalšej lekcii, 3D strieľačka v Unity - Úprava terénu , sa naučíme upravovať terén, pridávať stromy a trávu.


 

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 229x (1.74 kB)

 

Predchádzajúci článok
3D strieľačka v Unity - Efekty streľby
Všetky články v sekcii
Tvorba 3D hier v Unity
Preskočiť článok
(neodporúčame)
3D strieľačka v Unity - Úprava terénu
Článok pre vás napísal Tomáš Brabec
Avatar
Užívateľské hodnotenie:
2 hlasov
Hodně zdaru programátoři všeho druhu,doufám ,že nikdy nezažijete nudu.
Aktivity