Objektum mozgatás Unity-ben

Nem lenne játék a játék mozgó objektumok nélkül. Azt hihetnénk, hogy ez egy nagyon egyszerű dolog: csak arrébb kell tenni az adott objektumot minden képkockában. A gyakorlat egy kicsit más, több mozgatási módszer is létezik. Ez a leírás minimális programozási ismereteket feltételez, de a kezdők is el fognak tudni igazodni a szkriptekben.

Az alapok

Van egy objektumunk és egy 2D-s felületen, az X tengelyen szeretnénk jobbra/balra mozogni a nyíl gombokkal:

Objektum

    using UnityEngine;
    public class PlayerController : MonoBehaviour {
        Rigidbody rb;
        public float speed = 10.0f;
        void Start () {
            rb = GetComponent();
        }
      void Update () {
            if (Input.GetKey(KeyCode.RightArrow))
            {
                rb.velocity = transform.right * speed;
            }
        }
    }

Így mozog, ha megnyomjuk a jobbra nyilat:

Jobbra mozgatás

Valami nincs rendben! Ha jobbra akarunk menni, miért indul el balra egy idő után a golyó? Ennek az az oka, hogy a golyó vektorai együtt forognak az objektummal. Egy idő után a golyó átfordul, és a jobbra irányszámunkra máris balt jelent.

Rögzíthetjük a golyót, hogy ne forogjon, ha befagyasztjuk a forgását:

    rb.freezeRotation = true;

Miután a sebességet 2.0f-re változtattuk, és a fenti sort hozzáadtuk, ilyesmi eredményt kapunk:

Jobbra mozgatás

Ez már jobban néz ki, de még mindig javíthatunk rajta.

Balra is szeretnénk menni, ehhez kicsit módosítani kell a kódon:

    using UnityEngine;
    public class PlayerController : MonoBehaviour {
        Rigidbody rb;
        public float speed = 2.0f;
        void Start () {
            rb = GetComponent();
            rb.freezeRotation = true;
        }
      void Update () {
            if (Input.GetKey(KeyCode.RightArrow))
            {
                rb.velocity = transform.right * speed;
            }
            if (Input.GetKey(KeyCode.LeftArrow))
            {
                rb.velocity = -transform.right * speed;
            }
        }
    }

Mivel nincs transform.left funkció, ezért a transform.right funckiót kell tükrözni, azzal hogy elé teszünk egy mínusz jelet.

A módosítások után már tudunk jobbra és balra is mozogni a golyóval. Amennyiben további dimenziókat szeretnénk hozzáadni a mozgáshoz, akkor a Z tengelyen történő elmozdulást kell kezelnünk, hogy a talaj mentén tudjunk közlekedni.

Az előre történő mozgáshoz a következő sort kell használnunk:

    rb.velocity = new Vector3(0, 0, 1) * speed;

Ez azt eredményezi, mint a fenti példa, de egy 3D-s vektort hív ehhez segítségül.

A teljes kód:

    using UnityEngine;
    public class PlayerController : MonoBehaviour {
        Rigidbody rb;
        public float speed = 2.0f;
        void Start () {
            rb = GetComponent();
            rb.freezeRotation = true;
        }
      void Update () {
            if (Input.GetKey(KeyCode.RightArrow))
            {
                rb.velocity = transform.right * speed;
            }
            if (Input.GetKey(KeyCode.LeftArrow))
            {
                rb.velocity = -transform.right * speed;
            }
            if (Input.GetKey(KeyCode.UpArrow))
            {
                rb.velocity = new Vector3(0, 0, 1) * speed;
            }
            if (Input.GetKey(KeyCode.DownArrow))
            {
                rb.velocity = new Vector3(0, 0, -1) * speed;
            }
        }
    }

Mozgás minden irányban

A második módszer

Létezik alternatív megoldás is arra, hogy a golyót mozgassuk. Eddig a transform funkciókat használtuk, ami nem ad túl realisztikus mozgást. Az Input.GetAxis() használatával lehetőségünk van realisztikusabban mozgtani az objektumokat, mivel a nyers, “tedd odébb” parancsok helyett fizikai erővel hatunk az objektumokra, így idézve elő a mozgást.

    using UnityEngine;
    public class PlayerController : MonoBehaviour {
        Rigidbody rb;
        public float speed = 2.0f;
        void Start () {
            rb = GetComponent();
        }
      void Update () {
            float moveHorizontal = Input.GetAxis("Horizontal");
            float moveVertical = Input.GetAxis("Vertical");
            rb.AddForce(new Vector3(moveHorizontal, 0.0f, moveVertical) * speed);
        }
    }

Görgetés

A mozgatás RigidBody alapú, így ha módosítjuk a tömeget, a súrlódást, az hatással lesz a mozgatási képességre is.

A harmadik módszer

Egy másik lehetőség, hogy sebességet adunk a golyónak a fel/le nyilakkal, és forgatjuk a balra/jobbra nyilakkal:

    using UnityEngine;
    public class PlayerController : MonoBehaviour {
        public float movementSpeed = 5.0f;
        public float rotationSpeed = 200.0f;
        void Update () {
            transform.Rotate(0, Input.GetAxis("Horizontal") * Time.deltaTime * rotationSpeed, 0);
            transform.Translate(0, 0, Input.GetAxis("Vertical") * Time.deltaTime * movementSpeed);
        }
    }

Mozgó mosolygó labda

Két lehetséges megoldást kombináltunk, így kaptuk meg a harmadikat. A transform funciókat és a GetAxis()-t használtuk, amely kiszámíthatóbb mozgást tesz lehetővé, ezért ez jól használható például versenyzős játékok esetében.

A Unity-nek van egy beépített karaktervezérlője is, erre is érdemes egy pillantást vetnünk:

Karakter kontroller

A kód, amellyel WASD gombokkal tudunk mozogni:

    using UnityEngine;
    public class PlayerController : MonoBehaviour {
        CharacterController characterController;
        public float movementSpeed = 5.0f;
        private Vector3 moveDirection = Vector3.zero;
        void Start()
        {
            characterController = GetComponent();
        }
        void Update () {
            if (characterController.isGrounded)
            {
                moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0.0f, Input.GetAxis("Vertical"));
                moveDirection = moveDirection * movementSpeed;
            }
            //Gravity
            moveDirection.y -= 10f * Time.deltaTime;
            characterController.Move(moveDirection * Time.deltaTime);
        }
    }

 

Ebben a megoldásban nem használjuk a RigidBody-t, így a gravitációt magunknak kell megírnunk.

Összegzés

A helyzettől függ, hogy melyik megoldást érdemes alkalmaznunk. Olyan esetben, amikor valaminek X idő alatt pontosan Y távolságot kell megtennie, kerüljük a fizikai erőkkel történő mozgatást, és inkább a transform paraméterek módosításával mozgassunk. A realisztikusabb mozgáshoz, amelyben a fizikát is alkalmazni akarjuk, az AddForce funcióval érdemes dolgoznunk.

Természetesen ezek nem kőbe vésett szabályok, lehetnek egy játékban olyan események is, amikor az AddForce alapú mozgatás a normál, míg bizonyos eseményeknél a velocity-vel kell operálni.

Forrás: Noob Programmer

Skeldar

0 válaszok

Hagyjon egy választ

Want to join the discussion?
Feel free to contribute!

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük