Vízszintes / függőleges látótér
Korábban láthattuk, hogy mind perspektív, mind pedig ortografikus kamera egy transzformált téglatestet vág ki a térből:
- Ortografikus kamera: Téglatest
- Perspektív kamera: Frusztum (Csapott tetejű piramis)
A különböző kameratípusokról bővebben: Virtuális kamerák
Hogy ez test a a kamera pozíciójához képest hol kezdődik és a milyen távol fejeződik be azt az elülső és hátulsó vágósík (vágó-távolság) határozta meg, a látótér mérete egy szám alapján volt állítható.
- Ortografikus kamera: Kamera által belátott magasság (Ortographic Size)
- Perspektív kamera: Kamera függőleges látószöge (Field of View)
Figyeljük meg, hogy mindkét esetben ezen értékek függőlegesek. Nincs arra lehetőség, hogy vízszintes szélességet és látószöget állítsunk egy kamerán. Ezen vízszintes értékeket mindig a megfelelő függőleges adatokból valamint a képernyő képarányából számolja ki a Unity.
(Hogy ezt miért nem lehet könnyedén szabályozni az jó kérdés… Főleg úgy hogy a perspektív esetben olyan mintha, lehetne. Ám ez senkit ne tévesszen meg. Próbáljátok csak meg beállítani a vízszintes Field of View-et majt méretezzétek át a Game ablakot. Egyből látjátok, hogy valójában ugyanúgy a függőleges látószög a fix.)
Azonban ne aggódjunk, könnyedén tudunk egy egyszerű saját szkriptet írni erre a célra.
Ehhez a Camera.aspect
lekérdezést használhatjuk fel, ami a képarányt adja meg.
Ortographic:
[SerializeField] float orthographicSize;
[SerializeField, Range(0, 1)] float useHorizontalSize;
// ...
float verticalSize = orthographicSize / Mathf.Lerp(1, camera.aspect, useHorizontalSize);
controlledCamera.orthographicSize = verticalSize;
Perspektív:
[SerializeField] float fieldOfView;
[SerializeField, Range(0, 1)] float useHorizontalFOV;
// ...
float verticalFOV = fieldOfView / Mathf.Lerp(1, camera.aspect, useHorizontalFOV);
camera.fieldOfView = verticalFOV;
Kamera nyílásszöge (Field of view), a célpont mérete és a távolságuk
Korábban láttuk, hogyan tudunk egy kamerát egy célpontra irányítani úgy, hogy a kettejük közti távolságot valamint a kamerának vízszintes és függőleges dőlésszögét adjuk meg beállításként:
Ha belegondolunk azonban, akkor a felhasználó / game designer számára általában nem az fontos, hogy milyen távol van a kamera a céltól, sokkal inkább az, hogy a célpont mekkorában látszik a képernyőn. Ez ortografikus kamera esetén egyszerűen beállítható az Ortographic Size segítségével, a kérdés perspektív kamera esetén trükkösebb, így a továbbiakban csak ezzel az esetett foglalkozunk.
3 egymással szorosan összefüggő paramétert vehetünk fel egy perspektív kameránál.
- :
targetDistance
: Atarget
objektum, azaz célpont és a kamera távolsága. - :
camera.fieldOfView
: a kamera függőleges nyílásszöge. - :
targetScale
: A belátott terület magassága a célpontban.
A három érték közül bármely kettőt tudjuk, akkor a harmadik kiszámolható a többiből.
Felrajzólhatunk a fenti adatokból egy derékszögű háromszöget (bár itt-ott osztani kell kettővel). Derékszögű háromszög esetén pedig tudjuk, hogy Pitagorasz tétel és a trigonometriai függvények segíthetnek kiszámolni a nem ismert változókat.
Mivel ezúttal egy szög és a befogók kapcsolatát akarjuk felvázolni a tangens függvény lesz segítségünkre, ugyanis:
Szög tangens-e: Szöggel szemközti és a szög melletti befogó hányadosa.
Tehát a következő összefüggés írható le:
Ezt az képletet átalakíthatjuk, úgy hogy a fenti paraméterek közül bármely kettőt kiválasztva megkapjuk a harmadikat:
Most eldönthetjük, hogy a programunkban melyik kettő paraméter lesz egy beállítás és melyik lesz az, amelyiket származtatjuk a másik kettőből.
Nálam a targetDistance
lesz a származtatott:
[SerializeField] Camera controlledCamera;
[SerializeField] Transform target;
[SerializeField] float targetScale = 1; // A célpont mérete
[SerializeField] float fieldOfView = 30f; // Kamera nyílásszöge
void Update()
{
if(target == null) return;
if(controlledCamera == null) return;
controlledCamera.fieldOfView = fieldOfView;
float fieldOfViewRad = fieldOfView * Mathf.Deg2Rad;
float targetDistance = targetSize / (2 * Mathf.Tan(fieldOfViewRad / 2f));
// ... Camera pozíciójának beállítása távolság alapján: Korábbi leckében
}
A fentiek egybevonhatók a következő szkripttel: Célpontkövető kamera
A Dolly-zoom egy filmes kamera effekt, amit Alfred Hitchcock dolgozott ki Irmin Roberts operatőrrel a Szédülés című mára klasszikussá vált filmhez. (Korábban is kísérletezett az effekttel kevesebb sikerrel) Az effekt lényege, hogy úgy változtatja az operatőr a kamera zoom-ot, hogy közben a célpont és a kamera távolsága is módosul. A gyakorlatban egy sínen (dolly-n) mozog a kamera a cél felé.
Ezen effekttel megoldható, hogy a célobjektum mérete ne változzon, mégis drasztikusan átalakuljon a kép. Ezáltal kényelmetlen, idegen hatást kelthet a filmkészítő.