Construct is mainly designed for 2D games, but it also provides a range of features that allow you to add 3D elements to your games. This tutorial covers the available 3D features and how they work together.
Z Elevation
The simplest 3D feature in Construct is Z elevation. This lets you move otherwise 2D objects like Sprites up and down on the Z axis. Increasing the Z elevation will move the object towards the camera, so it appears bigger. Decreasing the Z elevation will move the object away from the camera, so it appears smaller. As the view scrolls around the layout, you'll notice that Z elevated objects also move differently to reflect their 3D position. It's a quick and easy way to move objects around in 3D. The On-rails shooter example is a good demonstration of the creative possibilities of using Z elevation.
Some Piggy sprites using Z elevation to show perspective
You can also change the Z elevation of entire layers. This moves all the objects on the layer up and down on the Z axis. This provides an interesting alternative to parallax, using real depth rather than changing the scroll speed. Placing a series of layers at different Z elevations is a quick way to get an overall 3D appearance in an otherwise 2D game.
The camera
Being focused on 2D games, Construct normally refers to scrolling and scale when describing which part of the layout is visible and how big it appears. However the view is actually rendered as a 3D world, with a camera position that determines what is visible.
In Construct, scrolling to a position moves both the camera and the position it looks at to the given X and Y co-ordinates. So scrolling is in fact moving the camera around in 2D.
By default the camera starts at a Z position of 100, and points down to look at a Z position of 0. All the normal 2D content of a layout has a Z position of 0 (unless it uses Z elevation). The camera is set up to ensure that objects 100 pixels away from the camera appear at 100% scale, so everything appears as expected for a 2D game.
Visualization of the camera at a Z position of 100 looking down at a layout with 2D content at a Z position of 0
Moving a sprite to a Z elevation of 50 means it is placed half-way towards the camera, and so appears twice as big. Similarly moving a sprite to a Z elevation of -100 means it is placed twice as far from the camera, and so appears half as big.
Scale/zoom
In Construct, adjusting the layout or layer scale (or in the editor, zooming in and out) actually moves the camera on the Z axis. For example at 2x scale (or 200% zoom), the camera is actually moved to a Z position of 50. Since the camera is closer to the content by a factor of 2, it appears bigger by a factor of 2. In 2D this does exactly what you expect, and everything scales accordingly. However there is an additional 3D side-effect to this: since the camera is moving on the Z axis, the perspective of 3D features changes accordingly. For example you'll notice Z elevated sprites moving in the view to reflect their position relative to the camera. This means scale/zoom is a true 3D effect in Construct, rather than just stretching everything bigger.
Calculating a camera Z position
The camera Z position for a 2D scale factor can be calculated with 100 / scale
. For example if scale is 2, for 2x scale, the camera position is 100 / 2 = 50
.
If you wish to set the camera Z position directly, you still have to use the Set layout/layer scale actions based on a 2D scale factor. However you can reverse the calculation and set the scale to 100 / z
. For example to set the camera position to 50, you'd set the scale to 100 / 50 = 2
. Alternatively you can use the 3D Camera object, which is covered below.
View distance
Due to the way 3D rendering works, the camera has both a minimum and a maximum distance in side which content is visible. If content is either too close to the camera or too far away, it will disappear.
In Construct the minimum distance is 1, and the maximum is 10000. Therefore anything closer than 1 unit away from the camera on the Z axis, or further away than 10000 units away on the Z axis, will not be visible. For example with the default camera position at Z=100, the highest a Sprite will be visible is at a Z elevation of 99. It won't be visible at 99.5, even though that is still in front of the camera (and naturally content behind the camera is not visible). Similarly a Sprite at a Z elevation of -9900 (which is the camera Z position 100 minus the maximum view distance of 10000) will be only just visible, but will completely disappear if any further away.
Vanishing point
The vanishing point determines how the perspective appears for 3D features. By default the vanishing point is in the middle of the viewport, meaning as objects move in to the distance, they also appear to move towards the middle of the screen. The vanishing point can be altered via the Vanishing point layout property and the Set layout vanishing point system action. The given position is relative to the viewport, with (0%, 0%) being the top-left corner of the viewport, and (100%, 100%) being the bottom-right corner of the viewport.
Changing the vanishing point can be useful to adapt the 3D perspective to match the style of your game. For example in a 3D platformer, it's useful to move the vanishing point up a little, so the tops of 3D shapes are visible when the player is standing on them (as demonstrated in the 3D platforms example). Alternatively moving the vanishing point to the bottom of the viewport might be useful for providing a more isometric style view, such as to view the faces of buildings if walking around a town made from 3D shape objects.
3D Camera
Instead of being limited to the 2D features described previously, the 3D Camera object allows complete control over the camera, allowing it to be positioned anywhere in 3D, and pointed to look at another 3D position. For an example of this, see the First-person shooter example. The Mouse object also supports pointer lock, which is useful for controlling the camera angle by mouse, a.k.a. "mouse look". See the First-person platformer example for an example of that.
Z scale
The 3D Camera uses the normalized Z axis described above, where the camera defaults to a Z position of 100. This means the Z axis works with a different scale to the X and Y axes, which are based on pixels. The 3D Camera Z scale property and ZScale expression gives you the number of pixels per unit on the Z axis, so you can also use pixels on the Z axis. For example to make a 3D shape exactly cube, it should have the same width and height, and a Z height of the pixel size divided by the Z scale.
Projection
The Projection layout property can change between the default perspective projection, where things get smaller as they get further away from the camera, and orthographic projection, where things stay the same size regardless of their distance to the camera, creating a flat appearance. For an interactive example of both, see the Orthographic projection example.
Note that only the perspective projection takes in to account the vanishing point, as the orthographic projection has no perspective. The vanishing point also affects perspective when using 3D views with 3D Camera.
Collisions
All 3D features in Construct are cosmetic only - they don't affect how collisions work. Collisions still continue to work as if the object has a Z elevation of 0, i.e. as if it's still 2D. This is just something to bear in mind as you develop games using 3D features. In some cases you might want to disable collisions for objects using 3D features, such as if you want the player to be able to run underneath them.
Draw order
Construct uses a back-to-front renderer, which means it starts drawing things furthest away from the camera first, and then draws closer content on top. Since the last thing drawn is top of the Z order, it appears on top.
In Construct, Z elevation takes precedence over Z order. In other words, you can't use Bring to front to make something appear on top of something else with a higher Z elevation. The sort order is based on Z elevation first, and then the Z order is only used where multiple objects have the same Z elevation. Another way to think about this is Z order is a 2D feature. In a purely 2D game everything is at the same Z elevation of 0, and so Z ordering solely decides the appearance.
The draw order has an impact on transparency in some circumstances, and for 3D layers can be changed to a Camera distance draw order instead. For more details see the dedicated section on transparency below.
3D shape
The 3D Shape plugin provides an easy way to add further elements of 3D to your project. You can choose from a range of pre-defined shapes, such as a box, and draw images for each face of the shape. For more comprehensive coverage, refer to the linked manual entry. You can also try out the 3D shape tour example in Construct for an interactive tour.
Example of some 3D shape objects using the 'Box' shape
As with 2D objects, you can use the same Z elevation property to move 3D shapes up and down on the Z axis. The 3D shape object also has a Z height property that determines how tall it is, i.e. its depth. The Z height must be positive - if you want a 3D shape to appear lower down, move its Z elevation down instead. The Z height works in the same units as Z elevation, so a Z height of 25 would be a quarter of the distance to the camera (assuming defaults for everything else).
Transparency
Due to the way 3D rendering works, transparency may not always work as expected with 3D shape objects, especially when using 3D Camera. To correctly render 3D features, Construct must use a depth buffer. However this only supports fully opaque or fully transparent pixels. 3D shape objects generally work best with fully opaque images (not using any opacity).
Making individual faces invisible works as expected, as this means the face skips drawing entirely. Fully transparent pixels (with opacity 0) also work as expected, as these pixels do not fill in the depth buffer. However using semitransparent pixels, with an opacity in between fully opaque and fully transparent, is more difficult. Semitransparency also frequently occurs when using linear sampling, as semitransparent pixels may be drawn in between fully opaque and fully transparent pixels.
Semitransparency in 3D Shape's images may work in some circumstances, but it depends on Construct's draw order. So long as a 3D shape object using semitransparency is drawn after the content visible behind it, the result will appear correct. This is because the semitransparent content will be drawn on top of the content behind it. However if the 3D shape is drawn before content visible behind it, then the semitransparent portions of its faces will block rendering of the content drawn afterwards. This is because the semitransparent parts of its images are filled in to the depth buffer as if they are opaque, and then content meant to appear behind it is assumed to be invisible, and so is not rendered. As noted in the section on Draw order above, Construct's default draw order is back-to-front, starting with the furthest away Z elevation and moving forwards, and using Z order where the Z elevation is the same. Therefore adjusting Z elevation or Z order may be able to work around semitransparency related issues with 3D shapes.
Illustration of unexpected results with semitransparency on a side face of a 3D shape object. Left: the Piggy sprite is Z elevated just below the 3D shape, and semitransparency works as expected as the piggy is drawn first. Right: the Piggy sprite is Z elevated just above the 3D shape, and semitransparency does not work as expected as the piggy is drawn last.
Note that the draw order ignores the Z height of the 3D shape: the draw order is based only on its Z elevation, which is the position of the base of the object, and then by its Z order. Problems with semitransparency usually occur when the Z height of a 3D shape extends above content that comes after it in the draw order, i.e. at a higher Z elevation or Z order.
Semitransparency issues are limited to only 3D shape objects or when using a 3D camera. Z elevation with things like 2D sprites never has any issues with semitransparency, as the back-to-front draw order always works correctly. It is only with 3D shape objects that you should consider using only opaque images.
Semitransparency and draw order
Another tool to help with rendering semitransparency in 3D is the Draw order layer property. The default draw order is based on Z order as described above. However 3D layers can be changed to use a Camera distance draw order. This ignores the Z order of objects on the layer and instead draws things based on how far away from the camera they are, from furthest away to nearest. This is helpful for semitransparency as it ensures semitransparent content is always drawn after anything behind it. This is particularly useful when using the side faces of 3D shapes as "billboards", so they appear flat against the camera, with images that have semitransparency. A useful technique is to arrange layers like this:
- All opaque 3D scenery is on its own layer.
- All objects with semitransparency are on a separate layer above the scenery, with the Camera distance draw order.
This ensures the semitransparent content is always rendered correctly, as it is drawn in back-to-front order relative to the camera view, with each semitransparent object correctly overdrawing content behind it.
Transparency and fog
Even with the setup described above that renders semitransparency correctly, adding fog to the layer with semitransparent content may not appear correctly. The reason for this is once again that semitransparent pixels still fill in the depth buffer, and the fog effect fades to a color based on depth. So after rendering the whole layer, semitransparent parts of images will have a level of fog applied depending on how near the semitransparent content is to the camera, which will be less than the content further away behind it. In other words this means semitransparent content can still appear to have boxes around them where there is less fog than there ought to be.
The solution is to remove the fog effect from the layer, and instead apply the fog effect to the objects on the layer. Since the layer will be using the camera distance draw order to render transparency correctly, each individual object will be drawn in back-to-front order relative to the camera. Then the fog effect will be drawn with each individual object before anything else is drawn on top, ensuring it gets a level of fog appropriate for that object, rather than a potentially different level of fog based on something in front of it.
Best approaches
A few good approaches for dealing with transparency in 3D content are listed below, starting with the simplest options first:
- Use opaque images for 3D shapes. This completely avoids transparency-related problems.
- Use only images which are either fully opaque or fully transparent, avoiding any semitransparency. Then set the project Sampling property to Nearest. This avoids any linear filtering introducing semitransparent pixels in between opaque and transparent pixels. This is often suitable for retro/pixel art style 3D content.
- Use semitransparency, but carefully manage the layers and draw orders to ensure everything is drawn in the correct order, as explained above. This needs particularly careful management if fog is also used.
Mesh Z elevation
Construct's mesh distortion feature allows you to deform objects by splitting them in to a grid of mesh points that can be independently moved around. You can see this in action in the Mesh distortion example.
In both the mesh editor and at runtime, mesh points can also individually be moved on the Z axis with a Z elevation property. This provides another way to make customised 3D appearances in your project, and could even be used as a limited kind of 3D modelling. For an example of how dynamic mesh Z elevation looks, see the Mesh Z elevation example.
Using 2D layers
Layers are another form of Z ordering. Content on a higher layer normally appears above content on a lower layer. However 3D features can override this. For example a tall 3D shape object can still overlap and cover up content on a higher layer.
In some cases this is unwanted. For example you may want a 2D backdrop image at a Z elevation of 0 to still display behind 3D features that have a lower Z elevation. Alternatively you may wish for the HUD or other user interface controls to appear in front of 3D features that have a higher Z elevation, or on top of a 3D view using the 3D Camera object.
In both cases you can solve this by changing the Rendering mode layer property to 2D. This ensures its content is drawn flat in 2D again ignoring the depth of any 3D features, and with Construct's standard 2D view instead of the 3D Camera view. You can see this in action in the example Combining 2D & 3D layers.
Demonstration of the effect of a 2D layer, with text objects on both 2D and 3D layers, illustrating how each overlaps 3D content
Advanced project settings
There are two project settings that can also affect 3D features: the project Rendering mode, and Anisotropic filtering. Normally you don't need to change these, as they both default to Auto which should do what you want. However advanced users may wish to adjust them. For example if you only use 3D features at runtime, such as by adjusting a mesh to use Z elevation during the game, you may wish to force the rendering mode to be 3D. For more information refer to the manual entry covering project properties.
Conclusion
Construct is fundamentally a 2D game engine, but provides a range of features that can add some exciting 3D elements to your games. These range from a simple Z elevation property through to 3D mesh distortion. Most of them preview in the Layout View, allowing quick experimentation and feedback. Try it out and see what you can do! You can also browse the Start Page for examples tagged 3D for more examples.