Kapitola 6.4: Systém kamer
Úvod
DayZ používá vícevrstvý systém kamer. Kamera hráče je spravována enginem prostřednictvím podtříd DayZPlayerCamera. Pro moddování a ladění umožňuje FreeDebugCamera volný let. Engine také poskytuje globální přístupové metody pro aktuální stav kamery. Tato kapitola pokrývá typy kamer, jak přistupovat k datům kamery a jak používat skriptované kamerové nástroje.
Aktuální stav kamery (globální přístupové metody)
Tyto metody jsou dostupné odkudkoli a vracejí stav aktivní kamery bez ohledu na její typ:
// Aktuální světová pozice kamery
proto native vector GetGame().GetCurrentCameraPosition();
// Aktuální směr kamery (jednotkový vektor)
proto native vector GetGame().GetCurrentCameraDirection();
// Převod světové pozice na souřadnice obrazovky
proto native vector GetGame().GetScreenPos(vector world_pos);
// Vrací: x = obrazovka X (pixely), y = obrazovka Y (pixely), z = hloubka (vzdálenost od kamery)Příklad --- kontrola, zda je pozice na obrazovce:
bool IsPositionOnScreen(vector worldPos)
{
vector screenPos = GetGame().GetScreenPos(worldPos);
// z < 0 znamená za kamerou
if (screenPos[2] < 0)
return false;
int screenW, screenH;
GetScreenSize(screenW, screenH);
return (screenPos[0] >= 0 && screenPos[0] <= screenW &&
screenPos[1] >= 0 && screenPos[1] <= screenH);
}Příklad --- získání vzdálenosti od kamery k bodu:
float DistanceFromCamera(vector worldPos)
{
return vector.Distance(GetGame().GetCurrentCameraPosition(), worldPos);
}Systém DayZPlayerCamera
Kamery hráčů DayZ jsou nativní třídy spravované řídicím systémem hráče enginu. Nejsou přímo vytvářeny ze skriptu --- místo toho engine vybere vhodnou kameru na základě stavu hráče (stojící, ležící, plavání, vozidlo, v bezvědomí atd.).
Typy kamer (konstanty DayZPlayerCameras)
ID typů kamer jsou definovány jako konstanty:
| Konstanta | Popis |
|---|---|
DayZPlayerCameras.DAYZCAMERA_1ST | Kamera z pohledu první osoby |
DayZPlayerCameras.DAYZCAMERA_3RD_ERC | Třetí osoba vzpřímeně (stojící) |
DayZPlayerCameras.DAYZCAMERA_3RD_CRO | Třetí osoba v podřepu |
DayZPlayerCameras.DAYZCAMERA_3RD_PRO | Třetí osoba vleže |
DayZPlayerCameras.DAYZCAMERA_3RD_ERC_SPR | Třetí osoba sprint |
DayZPlayerCameras.DAYZCAMERA_3RD_ERC_RAISED | Třetí osoba se zdviženou zbraní |
DayZPlayerCameras.DAYZCAMERA_3RD_CRO_RAISED | Třetí osoba v podřepu se zbraní |
DayZPlayerCameras.DAYZCAMERA_IRONSIGHTS | Míření přes mířidla |
DayZPlayerCameras.DAYZCAMERA_OPTICS | Míření přes optiku/puškohled |
DayZPlayerCameras.DAYZCAMERA_3RD_VEHICLE | Třetí osoba ve vozidle |
DayZPlayerCameras.DAYZCAMERA_1ST_VEHICLE | První osoba ve vozidle |
DayZPlayerCameras.DAYZCAMERA_1ST_UNCONSCIOUS | První osoba v bezvědomí |
DayZPlayerCameras.DAYZCAMERA_3RD_CLIMB | Třetí osoba lezení |
DayZPlayerCameras.DAYZCAMERA_3RD_JUMP | Třetí osoba skok |
Získání aktuálního typu kamery
DayZPlayer player = GetGame().GetPlayer();
if (player)
{
DayZPlayerCamera cam = player.GetCurrentCamera();
if (cam && cam.GetCameraName() == "DayZPlayerCamera1stPerson")
{
Print("Player is in first person");
}
}FreeDebugCamera
Soubor: 3_Game/entities/camera.c
Kamera volného letu používaná pro ladění a filmovou práci. Dostupná v diagnostických buildech nebo při povolení mody.
Přístup k instanci
static proto native FreeDebugCamera GetInstance();Tato statická metoda vrací singleton instanci volné kamery (nebo null, pokud neexistuje). Volejte ji jako FreeDebugCamera.GetInstance().
Klíčové metody
// Povolit/zakázat volnou kameru (zděděno z Camera)
proto native void SetActive(bool active);
proto native bool IsActive();
// Pozice a orientace
vector GetPosition();
void SetPosition(vector pos);
vector GetOrientation();
void SetOrientation(vector ori); // otočení, náklon, naklonění
// Směr kamery
vector GetDirection();Příklad --- aktivace volné kamery a teleportace:
void ActivateDebugCamera(vector pos)
{
FreeDebugCamera cam = FreeDebugCamera.GetInstance();
if (cam)
{
cam.SetActive(true);
cam.SetPosition(pos);
cam.SetOrientation(Vector(0, -30, 0)); // Mírně pohled dolů
}
}Zorné pole (FOV)
Engine řídí FOV nativně. Můžete jej číst a upravovat prostřednictvím systému kamery hráče:
Čtení FOV
// Získat aktuální FOV kamery (v radiánech)
float fov = Camera.GetCurrentFOV();Přepsání FOV v DayZPlayerCamera
Ve vlastních třídách kamery, které rozšiřují DayZPlayerCamera, můžete přepsat FOV:
class MyCustomCamera extends DayZPlayerCamera1stPerson
{
override void OnUpdate(float pDt, out DayZPlayerCameraResult pOutResult)
{
super.OnUpdate(pDt, pOutResult);
pOutResult.m_fFovAbsolute = 0.7854; // ~45 stupňů (radiány)
}
}Hloubka ostrosti (DOF)
Hloubka ostrosti je řízena prostřednictvím systému post-processingových efektů (viz Kapitola 6.5). Systém kamer však pracuje s DOF prostřednictvím těchto mechanismů:
Nastavení DOF přes CGame
// OverrideDOF(enable, focusDistance, focusLength, focusLengthNear, blur, focusDepthOffset)
GetGame().OverrideDOF(true, 5.0, 100.0, 0.5, 0.3, 0.0);Vypnutí DOF
GetGame().OverrideDOF(false, 0, 0, 0, 0, 1); // První argument false vypne DOFScriptCamera (GameLib)
Soubor: 2_GameLib/entities/scriptcamera.c
Nízkoúrovňová skriptovaná entita kamery z vrstvy GameLib. Toto je základ pro vlastní implementace kamer.
Vytvoření kamery
ScriptCamera camera = ScriptCamera.Cast(
GetGame().CreateObject("ScriptCamera", pos, true) // pouze lokální
);Klíčové metody
Poznámka:
ScriptCamerase kompiluje pouze pod#ifdef GAME_TEMPLATEa není přítomna v herním buildu DayZ. Konfiguruje se prostřednictvím kamerových metod třídyGenericEntity(SetCameraVerticalFOV,SetCameraNearPlane,SetCameraFarPlane,SetCameraType). Níže uvedené metody patří k enginové tříděCamera(3_Game/entities/camera.c), kterouFreeDebugCamerarozšiřuje:
proto native void SetFOV(float fov); // FOV v radiánech
proto native void SetNearPlane(float nearPlane); // interně omezeno na 0.01m
proto native float GetNearPlane();
proto native void SetFocus(float distance, float blur); // hloubka ostrostiAktivace kamery
// Nastavit tuto kameru jako aktivní renderovací kameru
GetGame().SelectPlayer(null, null); // Odpojit od hráče
GetGame().ObjectRelease(camera); // Uvolnit pro enginePoznámka: Přepnutí z kamery hráče vyžaduje pečlivé zacházení se vstupy a HUD. Většina modů používá volnou debug kameru nebo PPE překryvné efekty místo vytváření vlastních kamer.
Raycast z kamery
Běžný vzor je provádění raycastu z pozice kamery ve směru kamery pro nalezení toho, na co se hráč dívá:
Object GetObjectInCrosshair(float maxDistance)
{
vector from = GetGame().GetCurrentCameraPosition();
vector to = from + (GetGame().GetCurrentCameraDirection() * maxDistance);
vector contactPos;
vector contactDir;
int contactComponent;
set<Object> hitObjects = new set<Object>;
if (DayZPhysics.RaycastRV(from, to, contactPos, contactDir,
contactComponent, hitObjects, null, null,
false, false, ObjIntersectView, 0.0))
{
if (hitObjects.Count() > 0)
return hitObjects[0];
}
return null;
}Shrnutí
| Koncept | Klíčový bod |
|---|---|
| Globální přístupové metody | GetCurrentCameraPosition(), GetCurrentCameraDirection(), GetScreenPos() |
| Typy kamer | Konstanty DayZPlayerCameras (1ST, 3RD_ERC, IRONSIGHTS, OPTICS, VEHICLE atd.) |
| Aktuální typ | player.GetCurrentCamera().GetCameraName() |
| Volná kamera | FreeDebugCamera.GetInstance(), pak cam.SetActive(true) |
| FOV | Camera.GetCurrentFOV() pro čtení, nastavit pOutResult.m_fFovAbsolute v OnUpdate |
| DOF | GetGame().OverrideDOF(enable, focusDist, focusLen, focusLenNear, blur, offset) |
| Převod na obrazovku | GetScreenPos(worldPos) vrací pixel XY + hloubku Z |
Osvědčené postupy
- Cachujte pozici kamery při opakovaném dotazování v rámci jednoho snímku.
GetGame().GetCurrentCameraPosition()aGetCurrentCameraDirection()jsou volání enginu -- uložte výsledek do lokální proměnné, pokud ho potřebujete ve více výpočtech v rámci jednoho snímku. - Používejte kontrolu hloubky
GetScreenPos()před umístěním UI. Vždy ověřtescreenPos[2] > 0(před kamerou) před vykreslováním HUD značek na světových pozicích, jinak se značky objeví zrcadlově za hráčem. - Vyhněte se vytváření vlastních instancí ScriptCamera pro jednoduché efekty. FreeDebugCamera a systém PPE pokrývají většinu filmových a vizuálních potřeb. Vlastní kamery vyžadují pečlivou správu vstupů/HUD, která se snadno rozbije.
- Respektujte přechody typů kamer enginu. Nevynucujte změny typu kamery ze skriptu, pokud plně nezvládáte stav řídicího systému hráče. Neočekávané přepnutí kamery může zablokovat pohyb hráče nebo způsobit desynchronizaci.
- Zabezpečte použití volné kamery za kontrolou admin/debug oprávnění. FreeDebugCamera poskytuje neomezený pohled na svět. Povolte ji pouze pro ověřené administrátory nebo diagnostické buildy, aby se předešlo zneužití.
Kompatibilita a dopad
- Multi-Mod: Přístupové metody kamery jsou globální jen pro čtení, takže více modů může bezpečně číst stav kamery současně. Konflikty vznikají pouze pokud dva mody oba aktivují FreeDebugCamera nebo vlastní instance ScriptCamera.
- Výkon:
GetScreenPos()aGetCurrentCameraPosition()jsou lehká volání enginu. Raycast z kamery (DayZPhysics.RaycastRV) je náročnější -- omezte na jednou za snímek, ne za entitu. - Server/Klient: Stav kamery existuje pouze na klientovi. Všechny metody kamery vracejí bezvýznamná data na dedikovaném serveru. Nikdy nepoužívejte dotazy na kameru v serverové logice.
<< Předchozí: Počasí | Kamery | Další: Post-processingové efekty >>
