A camera in Defold is a component that changes the viewport and projection of the game world. The camera component defines a bare bones perspective or orthographic camera that provides a view and projection matrix to the render script.
A perspective camera is typically used for 3D games where the view of the camera and the size and perspective of objects is based on a view frustum and the distance and view angle from the camera to the objects in the game.
For 2D games, it is often desirable to render the scene with an orthographic projection. This means that the view of the camera is no longer dictated by a view frustum, but by a box. Orthographic projection is unrealistic in that it does not alter the size of objects based on their distance. An object 1000 units away will render at the same size as an object right in front of the camera.
To create a camera, right click a game object and select Add Component ▸ Camera. You can alternatively create a component file in your project hierarchy and add the component file to the game object.
The camera component has the following properties that defines the camera frustum:
To activate a camera and have it feed its view and projection matrices to the render script, you send the component an acquire_camera_focus
message:
msg.post("#camera", "acquire_camera_focus")
Each frame, the camera component that currently has camera focus will send a set_view_projection
message to the “@render” socket, i.e. it will arrive to your render script:
-- 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
The camera component supplies the render script with either a perspective or orthographic projection matrix depending on the Orthographic Projection property of the camera. The projection matrix also takes into account the defined near and far clipping plane, the field of view and the aspect ratio settings of the camera.
The view matrix provided by the camera defines the position and orientation of the camera. A camera with an Orthographic Projection will center the view on the position of the game object it is attached to, while a camera with a Perspective Projection will have the lower left corner of the view positioned on the game object it is attached to.
For reasons of backwards compatibility the default render script ignores the projection provided by the camera and always uses an orthographic stretch projection. Learn more about the render script and the view and projection matrices in the Render manual.
You can tell the render script to use the projection provided by the camera by sending a message to the render script:
msg.post("@render:", "use_camera_projection")
You pan/move the camera around the game world by moving the game object the camera component is attached to. The camera component will automatically send an updated view matrix based on the current x and y axis position of the camera.
You can zoom in and out when using a perspective camera by moving the game object the camera is attached to along the z-axis. The camera component will automatically send an updated view matrix based on the current z-position of the camera.
You can zoom in and out when using an orthographic camera by changing the Orthographic Zoom property of the camera:
go.set("#camera", "orthographic_zoom", 2)
You can have the camera follow a game object by setting the game object the camera component is attached to as a child of the game object to follow:
An alternative way is to update the position of the game object the camera component is attached to every frame as the game object to follow moves.
When the camera has panned, zoomed or changed it’s projection from the default orthographic Stretch projection the mouse coordinates provided in the on_input()
lifecycle function will no longer match to the world coordinates of your game objects. You need to manually account for the change in view or projection. Converting from mouse/screen coordinates to world coordinates from the default render script is done like this:
The third-party camera solutions mentioned in this manual provides functions for converting to and from screen coordinates.
-- 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
You can manipulate cameras in runtime through a number of different messages and properties (refer to the API docs for usage).
A camera has a number of different properties that can be manipulated using go.get()
and go.set()
:
fov
number
).near_z
number
).far_z
number
).orthographic_zoom
number
).aspect_ratio
number
).view
matrix4
).projection
matrix4
).There is a library camera solution that implements common camera features such as game object follow, screen shake, screen to world coordinate conversion and so on. It is available from the Defold community assets portal:
Did you spot an error or do you have a suggestion? Please let us know on GitHub!
GITHUB