A kamera koordinátarendszerei
Több féle módon tudjuk lekérni a kurzor pozícióját attól függően mire és hogyan akarjuk használni az információt. Ehhez háromféle koordinátarendszert kell megérteni. Mindegyik koordináta 3D-s.
- World Position - Világkoordináta
- Screen Position - Képernyőkoordináta
- ViewPort Poistion - VievPort koordináta
Ezt már jól ismerjük. A 3D-s tér globális koordinátarandszere.
A pozíció a játékot futtató ablakon belül pixelben megadva. Ez csak egy kamerán értelmezett.
A Screen helyvektor x és y komponense megadja az kurzor vízszintes és függőleges távolságát az ablak bal alsó sarkától pixelben megadva.
A z komponens a kamerától való távolság a Unity egységeiben mérve. Ha pont a kamera pozíciójában állunk, akkor z==0, ha 20 egységre előtte, akkor 20.
(Perspektív kamera esetén ez pont a kamerától való távolság, ortografikus kamerán azonban a távolságot csak a kamera tengelye mentén értelmezzük.)
Pozíció a játékot futtató ablakban 0 és 1 közt, ahol
viewPortPosition.x == 0 Az ablak baloldala
viewPortPosition.x == 1 Az ablak jobboldala
viewPortPosition.y == 0 Az ablak alja
viewPortPosition.y == 1 Az ablak teteje
A z komponens a Screen pozícióban is a kamera előtti távolságot adja szimpla egységekben kifejezve.
Tetszőlegesen tudunk váltani a Screen, ViewPort és World pozíciók közt. Ehhez persze ismernünk kell a Camera referenciáját.
Vector3 screenPos, worldPos, viewportPos;
Camera camera = Camera.main; // Más kamera is lehetne
//...
worldPos = camera.ScreenToWorldPoint(screenPos);
screenPos = camera.WorldToScreenPoint(worldPos);
viewportPos = camera.ScreenToViewportPoint(screenPos);
screenPos = camera.ViewportToScreenPoint(viewportPos);
worldPos = camera.ViewportToWorldPoint(viewportPos);
viewportPos =camera.WorldToViewportPoint(worldPos);Kurzor pozíciója
…Screen pozícióban
A kurzor pozícióját legegyszerűbben Screen pozícióban kérhetjük le.
Vector3 screenPos = Input.mousePosition;
Ez egy Vector3 értékkel tér vissza, aminek x és y komponense megadja az kurzor vízszintes és függőleges távolságát az ablak bal alsó sarkától pixelben megadva.
A z komponens a Screen pozícióban a kamera előtti távolság. Ez nem állapítható meg a kurzorról, tehát az eredmény nulla lesz.
…ViewPort pozícióban
A ViewPort pozíciót a korábbi Screen pozíció alapján kérhetjük le.
Ennek megállapításához szükséges a kamera referenciája (pl.: Camera.main).
Vector3 viewPortPos = Camera.main.ScreenToViewportPoint(screenPos); ahol
A z komponens megint csak a kamera előtti távolság. A lekérdezés erre a tengelyre pontosan azt adja vissza a kimeneten, amit a bemeneten kapott.
…World pozícióban
A 3D-s térbeli pozíciót is a Screen pozíció alapján kérhetjük le.
Ehhez szintén kell a kamera referenciája és ezúttal a kamerától vett távolság is, amit előre be kell állítani a bemeneti változón: screenPos.z = distance;
Ezután kérhetjük le a world- azaz világkoordinátát.
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
Raycast
Ha azt szeretnénk tudni, hogy mely tárgyra mutat az egér és a térben mi a találkozás pozíciója azt a Raycast vagy magyarosan sugárvetés fejezetben fogjuk tárgyalni.
Az egér pozíció változása
Ha csak arra vagyunk kíváncsi, mennyit mozgott az egér az előző képfrissítés (frame) óta, akkor azt a legegyszerűbben két GetAxis lekérdezéssel tudjuk megtenni:
float mouseDeltaX = Input.GetAxis("Mouse X"); // Vízszintes tengely
float mouseDeltaY = Input.GetAxis("Mouse Y"); // Függőleges tengely
Vector2 mouseDelta = new(mouseDeltaX, mouseDeltaY);Az eredményt itt is képernyő koordinátában, azaz pixelben kapjuk meg.
A módszer előnye, hogy ha így kérjük le az egér mozgását, akkor mindig fogunk visszakapni nem nulla input értéket, ha az egeret fizikailag mozgatjuk. Még akkor is, amikor a kurzor nekiütközött a képernyő szélének és nem tud tovább menni.
Ezért ez a lekérdezés ideális például First és Third Person játékok kamerájának mozgatására. Ekkor általában nem is akarjuk látni a kurzort. Ezt a következő paranccsal tudjuk elérni.
Cursor.visible = false;Ezt elég egyszer elvégezni mondjuk egy Start() metódusban.
Kattintás lekérdezése
Kattintások állapotát hasonlóan lehet lekérdezni, mint ahogy azt a GetKey… parancsokkal lehetett a billentyűk esetén. Lekérhető a lenyomás felengedés és lenyomva tartás.
Az alábbi metódusok mindegyike egy bool-lal tér vissza, ami igaz lesz a következő esetekben:
Input.GetMouseButtonDown(index) Abban a frame-ben, amikor az egér gombját épp lenyomjuk.
Input.GetMouseButtonUp(index) Abban a frame-ben, amikor az egér gombját épp felengedtük.
Input.GetMouseButtonDown(index) Addig, amíg az egér gombját lenyomva tartjuk.
A fenti metódusok mindegyik egy int típusú (index) paramétert vár, ami megmondja melyik egérgombot kérdezzük le:
0 - Bal egérgomb
1 - Jobb egérgomb
2 - Középső egérgomb (görgő)
3 - Bal elülső oldalgomb
4 - Bal hátsó oldalgomb
5 - Jobb elülső oldalgomb
6 - Jobb hátsó oldalgomb
Példakód:
void Update()
{
if (Input.GetMouseButtonDown(0))
Debug.Log("Pressed primary button."); // BAL egérgombot épp lenyomtuk
if (Input.GetMouseButtonDown(1))
Debug.Log("Pressed secondary button."); // JOBB egérgombot épp lenyomtuk
if (Input.GetMouseButtonDown(2))
Debug.Log("Pressed middle click."); // KÖZÉPSŐ egérgombot épp lenyomtuk
}Az egér Unity üzenet metódusai
Képesek vagyunk kezelni bizonyos az egérrel és Collider-rel összefüggő eseményeket Unity üzenet metódusok segítségével.
Ahhoz, hogy a következő metódusokat meghívja a Unity szükséges, hogy egy 2D vagy 3D Collider hozzá legyen adva ugyanazon GameObject-hez, amin a MonoBehaviour komponensünk is szerepel.
Az események lefutása attól függ, hogy az egér milyen módon lép kapcsolatba ezen Collider-ekkel.
OnMouseEnter - Abban a frame-ben (képkockában) egyszer, amikor az egér belép a Collider-be.
OnMouseExit - Az első frame-ben egyszer, amikor az egér már elhagyta a Collider-t.
OnMouseOver - Minden frame-ben addig, amíg az egér a Collider-en belül van.
OnMouseDown - Abban a frame-ben egyszer, amikor az egér gombját épp lenyomjuk a Collider-en.
OnMouseUp - Az első frame-ben egyszer, amikor az egér gombját már felengedtük.
OnMouseDrag - Minden frame-ben addig, amíg az egér gombját lenyomva tartjuk.
Megjegyzések:
- A fenti metódusokat az
Updateelőtt hívja meg a motor. - A fentiek akkor is működnek, ha a Collider egy trigger.
- Az
OnMouseEnter-rel egy frame-ben le fog futni azOnMouseOveris. - Ezzel szemben az első
OnMouseDragazOnMouseDownután fut le. - Az
OnMouseUpés azOnMouseDraglefutásához nem szükséges, hogy az egér még mindig a Collider felett legyen, csak akkor, mikor korábban lenyomták a gombot. - Az
OnMouseDragelőtt lefut azOnMouseOveris, ha az egér még mindig a Collider felett áll. - Az
OnMouseDown,OnMouseUpésOnMouseDragcsak a ball egérgombot figyeli.
Ahhoz, hogy egy másik, mondjuk a jobb egérgomb kattintás eseményeit is hasonlóan el tudjuk kapni extra kód szükséges. Erre itt láthattok egy példát:
Drag&Drop
A fentiek használata elég ahhoz, hogy egy egyszerű mozgató szkriptet írjunk. Ha ezt hozzáadjuk egy GameObject-hez, akkor azt Drag&Drop módszerrel odébb tehetjük.
Érintés Input
Az okostelefonokon és táblagépeken az érintés segítségével tudjuk kontrollálni a játékunkat. Ha egyszerre csak egy érintést akarunk kihasználni, akkor használhatjuk a egér eseményeit és lekérdező függvényeit a fenti módon.
Ha több párhuzamos érintést is szeretnénk kezelni, az kissé komplikáltabb.
Itt foglalkozunk vele bővebben: Érintés Input (Hamarosan)