Bevezetés

Folytatjuk az FPS Unity játékunk fejlesztését az egyik legizgalmasabb résszel, a fegyver és a rakéta viselkedésének programozásával. Ahogyan eddig is, a kódolást a minimumra fogjuk leszorítani, így a programozásban kevésbé jártasak is boldogulnak majd.

FPS Unity Rakéta robbanás ütközéskor

Írjunk egy szkriptet, amely érzékeli, ha valamivel ütközik a rakétánk! A Create/C# Script menüvel hozzunk létre egy Rocket elnevezésű szkriptet, amelynek két publikus változója és egy metódusa lesz:

using UnityEngine;
using System.Collections;

public class Rocket : MonoBehaviour {
    // The fly speed (used by the weapon later)
    public float speed = 2000.0f;

    // explosion prefab (particles)
    public GameObject explosionPrefab;

    // find out when it hit something
    void OnCollisionEnter(Collision c) {
        // show an explosion
        // - transform.position because it should be
        //   where the rocket is
        // - Quaternion.identity because it should
        //   have the default rotation
        Instantiate(explosionPrefab,
                    transform.position,
                    Quaternion.identity);

        // destroy the rocket
        // note:
        //  Destroy(this) would just destroy the rocket
        //                script attached to it
        //  Destroy(gameObject) destroys the whole thing
        Destroy(gameObject);
    }
}

Az OnCollisionEnter függvényt a Unity akkor fogja elindítani, amikor a rakéta ütközik valamivel. Ezek után már csak az Instantiate segítségével fel kell robbantanunk és a Destroy függvénnyel pedig meg kell szüntessük a rakéta GameObject-et.

Így fog kinézni a Rocket prefab-unk, miután hozzáadtuk a szkriptet:

Fps Unity Rocket prefab az Inspector-ban

Fps Unity Rocket prefab az Inspector-ban

Ideje felrobbantani a rakétát! A Unity ebben is segít, mivel a Particles asset-jében minden megtalálható, ami nekünk kell. Nézzünk szét a Standard Assets/Particle/Legacy Particles alatt és a Small explosion-t húzzuk be a Rocket szkript-be valahogy így:

Fps Unity Rocket prefab az Inspector-ban

Fps Unity Rocket prefab az Inspector-ban

Egy apróság: alapértelmezetten az Explode újra és újra felrobban, ezért a Small Explosion prefab-ot kiválasztva kapcsoljuk be a One Shot opciót. Ezzel a lépéssel be is fejeztük a rakétánkat, de lőni még mindig nem tudunk.

Small explosion az Inspector-ban

Érdekel a játékfejlesztés? Gyere el bemutató napunkra!

A rakéta kilövése

Ideje készítenünk egy új szkriptet, amelyet nevezzünk el Shoot-nak. A szkript feladata az lesz, hogy egy új rakétát hozzon létre minden alkalommal, amikor a játékos kattint. A kilövés a Rigidbody Addforce metódusával fog történni:

using UnityEngine;
using System.Collections;

public class Shoot : MonoBehaviour {
    // Rocket Prefab
    public GameObject rocketPrefab;

    // Update is called once per frame
    void Update () {
        // left mouse clicked?
        if (Input.GetMouseButtonDown(0)) {
            // spawn rocket
            // - Instantiate means 'throw the prefab into the game world'
            // - (GameObject) cast is required because unity is stupid
            // - transform.position because we want to instantiate it exactly
            //   where the weapon is
            // - transform.parent.rotation because the rocket should face the
            //   same direction that the player faces (which is the weapon's
            //   parent.
            //   we can't just use the weapon's rotation because the weapon is
            //   always rotated like 45° which would make the bullet fly really
            //   weird
            GameObject g = (GameObject)Instantiate(rocketPrefab,
                                                   transform.position,
                                                   transform.parent.rotation);

            // make the rocket fly forward by simply calling the rigidbody's
            // AddForce method
            // (requires the rocket to have a rigidbody attached to it)
            float force = g.GetComponent().speed;
            g.rigidbody.AddForce(g.transform.forward * force);
        }
    }
}

A kód egyetlen érdekes része a transform.parent.rotation sor. Ez fogja a rakétát pontosan előre elindítani (a játékos iránya alapján). Ha a transform.position -t használnánk, akkor a rakétánk a fegyverünk forward irányában indulna el, de mivel az kicsit balra van forgatva, így a rakéta is kicsit balra indulna el.

Mentsük el a szkriptet, majd adjuk hozzá a fegyverhez és húzzuk a Rocket Prefab slot-ba a rakétánk prefab-ját:

Egy kis módosításra még szükségünk lesz. Jelenleg kattintásnál a rakéta ott jelenik meg, ahol a fegyver is található, így onnan indul el a játékos forward irányában. Úgy programoztuk a rakétát, hogy azonnal felrobbanjon, ha ütközik valamivel, így létrehozás után azonnal fel is robban (amint megjelenik, ütközik a fegyverrel). Ezt legegyszerűbben úgy védhetjük ki, hogy a Collider komponenst kikapcsoljuk/eltávolítjuk a fegyverről vagy az azt alkotó Cube-okról.

Ha megnyomjuk a Play-t, már lövöldözhetünk is:

FPS Unity Lövöldözés rakétavetővel

FPS Unity Lövöldözés rakétavetővel

Fps Unity céltáblák

Adjunk néhány mozgó célpontot a játékhoz! Most is egy Unity alapelemmel (Cube) hozzunk létre valamilyen célpontot:

Célpont modell

A példában mi ezt a textúrát használtuk, de ízlés szerint választhatunk mást is:

Célpont textúra

Hozzunk létre két üres GameObject-et és jelöljük ki velük a bal és jobb oldali pontokat. Ezek között fog ide-oda ingázni a céltáblánk:

A mozgatáshoz szükségünk lesz egy BullsEye elnevezésű szkriptre, amely pár sorból fog állni:

using UnityEngine;
using System.Collections;

public class BullsEye : MonoBehaviour {
    // left and right marks
    public Transform left;
    public Transform right;

    // speed
    public float speed = 1.0f;

    // current direction (false means to the left, true means to the right)
    bool dir = false;
   
    // Update is called once per frame
    void Update () {
        if (dir) {
            // go closer to the right one
            transform.position = Vector3.MoveTowards(transform.position,
                                                     right.position,
                                                     Time.deltaTime * speed);

            // reached it?
            if (transform.position == right.position)
                dir = !dir; // go to opposite direction next time
        } else {
            // go closer to the left one
            transform.position = Vector3.MoveTowards(transform.position,
                                                     left.position,
                                                     Time.deltaTime * speed);

            // reached it?
            if (transform.position == left.position)
                dir = !dir; // go to opposite direction next time
        }
    }
}

A legérdekesebb rész a dir változó. Ha az értéke igaz, akkor a célpont a jobboldali GameObject felé halad, ha hamis, akkor pedig visszafelé. Az értékét minden célbaéréskor cseréljük, így a mozgás irányát is megfordítjuk.

Ha mindezeket beállítottuk, akkor a célpontunknak a videóban látottak szerint kell mozognia.

Összefoglaló:

Természetesen minden részleten lehet finomítani. El lehet rejteni a kurzort, hangokat, menürendszert lehet hozzáadni a játékhoz. A lövedékekhez füstcsóvát, becsapódási nyomokat lehet megjeleníteni:

Rakéta csóva

Komolyabb, komplexebb programozást igénylő fejlesztés az ellenfelek elhelyezése és a vezérlésük. A leírás csak az FPS játékok alapmechanikájára koncentrált, de így viszont tér nyílik a kísérletezésre. A játékunk bár kezdetleges, de remekül építkezhetünk rá:

FPS játék alap

Forrás: Noobtuts

Skeldar