Kamera (ang. camera) w Defoldzie jest komponentem, który zmienia widok i projekcję świata gry. Komponent kamery definiuje podstawową kamerę perspektywiczną lub ortograficzną, która dostarcza macierz widoku i projekcji do skryptu renderującego (ang. render script).
Kamera perspektywiczna jest zazwyczaj używana w grach 3D, gdzie widok kamery oraz wielkość i perspektywa obiektów oparte są na tzw. bryle widokowej (ang. view frustum) oraz odległości i kącie widzenia od kamery do obiektów w grze.
W grach 2D często pożądane jest renderowanie sceny za pomocą rzutu ortograficznego. Oznacza to, że widok kamery jest określany przez specjalną bryłę widokową - prostopadłościan. Rzut ortograficzny jest nierealistyczny, ponieważ nie zmienia rozmiaru obiektów na podstawie ich odległości. Obiekt oddalony o 1000 jednostek zostanie narysowany w takim samym rozmiarze jak obiekt tuż przed kamerą.
Aby utworzyć kamerę, kliknij prawym przyciskiem myszy na obiekcie gry i wybierz Add Component ▸ Camera. Możesz także utworzyć plik komponentu w hierarchii projektu (Outline) i dodać go do obiektu gry.
Komponent kamery ma następujące właściwości, które definiują bryłę kamery (frustum):
Aby aktywować kamerę i przekazać jej macierze widoku i projekcji do skryptu renderującego, wyślij komponentowi wiadomość acquire_camera_focus
:
msg.post("#camera", "acquire_camera_focus")
Co klatkę, komponent kamery, który obecnie ma fokus kamery, wyśle wiadomość set_view_projection
do gniazda "@render"
, czyli dotrze to do twojego skryptu renderującego:
-- builtins/render/default.render_script
--
function on_message(self, message_id, message)
if message_id == hash("set_view_projection") then
self.view = message.view -- [1]
self.projection = message.projection
end
end
Komponent kamery dostarcza skryptowi renderującemu macierz projekcji albo perspektywiczną, albo ortograficzną, w zależności od właściwości Orthographic Projection kamery. Macierz projekcji uwzględnia również określone płaszczyzny odcięcia bliskie i dalekie (near Z, far Z), pole widzenia (FOV) oraz ustawienia współczynnika proporcji kamery.
Macierz widoku dostarczana przez kamerę określa położenie i orientację kamery. Kamera z Projekcją Ortograficzną (Orthographic Projection) będzie miała widok wycentrowany na pozycji obiektu gry, do którego jest podłączona, podczas gdy kamera z Projekcją Perspektywiczną (Perspective Projection) będzie miała lewy dolny róg widoku na obiekcie gry, do którego jest podłączona.
Dla zachowania kompatybilności wstecznej domyślny skrypt renderujący ignoruje projekcję dostarczoną przez kamerę i zawsze używa rzutu ortograficznego. Dowiedz się więcej o skrypcie renderującym oraz macierzach widoku i projekcji w instrukcji do renderowania.
Możesz powiedzieć skryptowi renderującemu, aby używał projekcji dostarczonej przez kamerę, wysyłając wiadomość do skryptu renderującego.
msg.post("@render:", "use_camera_projection")
Aby przesuwać kamerę po obszarze gry, należy przesuwać obiekt gry, do którego jest przypisany komponent kamery. Komponent kamery automatycznie będzie wysyłał zaktualizowaną macierz widoku na podstawie bieżącej pozycji kamery wzdłuż osi X i Y.
Możesz przybliżać i oddalać, używając kamery perspektywicznej, przesuwając obiekt gry, do którego jest przypisana kamera, wzdłuż osi Z. Komponent kamery automatycznie będzie wysyłał zaktualizowaną macierz widoku na podstawie bieżącej pozycji kamery wzdłuż osi Z.
Możesz również przybliżać i oddalać, używając kamery ortograficznej, poprzez zmianę właściwości Orthographic Zoom kamery:
go.set("#camera", "orthographic_zoom", 2)
Kamerę można ustawić tak, aby śledziła obiekt gry, ustawiając obiekt gry, do którego przypisany jest komponent kamery, jako potomka obiektu gry, który ma być śledzony:
Alternatywnym sposobem jest aktualizacja pozycji obiektu gry, do którego przypisany jest komponent kamery, co klatkę, w miarę jak obiekt gry do śledzenia się przemieszcza.
Gdy kamera jest przesunięta, przybliżona lub zmieniła projekcję względem domyślnego rozciągniętego rzutu ortograficznego, współrzędne myszy na ekranie dostarczone w funkcji cyklu życia on_input()
nie będą już odpowiadać współrzędnym świata twoich obiektów gry. Musisz ręcznie uwzględnić zmianę widoku lub projekcji. Konwersja z współrzędnych myszy/ekranu na współrzędne świata z domyślnego skryptu renderującego wygląda tak:
Rozwiązania dla kamer od społeczności wymienione w tym podręczniku oferują funkcje do konwersji między współrzędnymi ekranu a świata.
-- builtins/render/default.render_script
--
local function screen_to_world(x, y, z)
local inv = vmath.inv(self.projection * self.view)
x = (2 * x / render.get_width()) - 1
y = (2 * y / render.get_height()) - 1
z = (2 * z) - 1
local x1 = x * inv.m00 + y * inv.m01 + z * inv.m02 + inv.m03
local y1 = x * inv.m10 + y * inv.m11 + z * inv.m12 + inv.m13
local z1 = x * inv.m20 + y * inv.m21 + z * inv.m22 + inv.m23
return x1, y1, z1
end
Kamery można manipulować w czasie rzeczywistym za pomocą różnych wiadomości i właściwości (patrz w dokumentacji API).).
Kamera ma wiele różnych właściwości (properties), które można manipulować za pomocą go.get()
i go.set()
:
fov
number
).near_z
number
).far_z
number
).orthographic_zoom
number
).aspect_ratio
number
).view
matrix4
).projection
matrix4
).Istnieje biblioteka wspomagająca kamery, która implementuje wspólne funkcje, takie jak śledzenie obiektu gry, trzęsienie ekranu, konwersja współrzędnych ekranu na współrzędne świata i inne. Jest dostępna na portalu zasobów społeczności Defold (Assets portal):
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB