Hour 13. 3D Graphics
    What You’ll Learn in This Hour:
    Adding 3D nodes to your game
    Importing meshes and models
    Working in the 3D editor view
    Manipulating 3D objects
    Placing, enabling, and scripting cameras
    So far, everything in this book has been in 2D. It’s simple, straightforward, and cozy, and it’s easy to understand. But sometimes, you want
    more—an extra dimension or a different lens through which to view your game. Sometimes, you want three sides of the coin. That’s why we’ll
    explore 3D graphics in this hour.
    In this hour, you’ll learn how to add 3D objects to your game and manipulate them in the editor and through code, and how to set up cameras to
    view your game properly.
    Spatial Node
    Godot was built from the ground up to fully support 2D and 3D. Because of that, everything in 3D works and looks very similar to the process in
    2D. Just as 2D nodes have a base node called
    Node2D and GUI nodes have a base node called
    Control, the base node of all 3D
    nodes is the
    Spatial node.
    Just like the
    Spatial node, all 3D nodes have a red color. And if you know how to use a certain 2D node, there’s a good chance you’ll find
    the same node for 3D simply by removing the letters “2D” from the node name.
    Let’s add a
    Spatial node to a scene.
    The New Transform
    In the inspector, take a look at the transform properties for this node (Figure 13.1). You’ll notice that it looks similar to the 2D transform, yet
    slightly different. The reason for this, of course, is that we now have a th
    i
    rd axis.
    FIGURE 13.1
    The new transform properties, which are present in every 3D node.
    Just as every 2D node has a position, a rotation degree, and a scale, every 3D node has a translation, a rotation, and a scale.
    Translation: the offset of this node from the origin of the scene.
    Rotation: the rotation of this node, in degrees, around each axis.
    Scale: the scale of this node along each axis.
    If you look in the 3D editor, the “origin of the scene” is depicted by the point where the three axes (red, green, and blue) meet (Figure 13.2).
    FIGURE 13.2
    The origin of the scene, shown in the editor. In code, it’s simply the point (0,0,0).
    With 3D nodes, an additional property is present: transform. This is a matrix of 12 numbers, and you can use it to set translation, rotation, and
    scale at the same time. This requires complex math, so it won’t be discussed further here.
    The Three Axes
    In 2D, everyone knows there’s an x-axis that runs horizontally, and a y-axis that runs vertically. But how does this translate to 3D? Well, there
    are two schools of thought:
    Yis up: The x-axis is left/right, the y-axis is up/down, and the z-axis is forward/backward.
    Z is up: The x-axis is left/right, the y-axis is forward/backward, and the z-axis is up/down.
    These differences stem from the background of people using 3D. For example, the “z is up” version is usually attributed to architects. They first
    draw a floor plan on paper in 2D (using x and y axes), leaving the z-axis for when they start building toward the sky.
    InGodot, the “y is up” variation is used. However, it is possible that other software uses the “z is up” strategy, in which case you will run into
    problems when importing your models. More on that later.
    111111111
    22222222NOTE
    Axes Are Color Coded
    Throughout all of Godot and most other 3D software, the three axes are color coded exactly the same way: the x-axis is red, the y-axis is green,
    and the z-axis is blue.
    The Metric System
    In 2D, everything was measured in pixels. In 3D, we can’t do the same thing. When we place the camera differently, the size of objects and the
    distance from the camera changes. In fact, we might even use a split screen in which each camera only uses half the screen width. This means
    using a fixed pixel unit doesn’t work in 3D.
    Instead, the metric system is used. When you set a node’s translation to, say, (50, 50, 0), it moves 50 meters to the right and 50 meters up
    within the scene.
    All professional 3D-modeling software uses this convention, so if you ensure that objects are the right size in your software, they should look
    perfect once imported to Godot.
    Models, Meshes, and Primitives
    If you look in your 3D editor, you don’t see anything, because the
    Spatial node has no geometry attached to it. It’s an empty node, just as
    Node2D. In fact, all 3D nodes have no visual presence, except for meshes.
    A mesh is nothing more than a collection of vertices (or dots), connected to each other to make edges (or lines), which are connected to get
    faces (or surfaces). In the image below, you can see that a cube has eight vertices, 12 edges, and six faces (Figure 13.3).
    FIGURE 13.3
    How meshes are built. (Obviously, there’s also a backside to this cube, but it doesn’t show in a 2D image.)
    A model is a collection of meshes that belong together. For example, a character might consist of multiple meshes—one for his head, and two
    for both his arms.
    A primitive is a “standard mesh,” such as a cube, sphere, pyramid, or cylinder.
    In the next chapter, we’ll look at how to import 3D models into Godot.
    NOTE
    Dynamic Meshes
    Sometimes, you’ll need to change meshes during the game or create new meshes on the fly. Godot offers the possibility to generate and
    manipulate meshes using GDScript with the
    ImmediateGeometry node, but it’s beyond the scope of this lesson.
    Note that this is different from animating an object. Everything you’ve learned in Hour 10 about animation also applies to 3D, and you can
    animate any object any way you want by keyframing the translation, rotation, or scale.
    Importing Meshes and Models
    In this chapter, I’ll assume you have 3D-modeling software installed on your computer, and that you know how to use it (at least a little). If not,
    Blender is a professional, free modeling software that you can install and use. All you need to do—for now—is add a cube to your scene and
    export it as an .obj file.
    When it comes to importing, there are two options:
    Importing a single mesh: This gives you more control, as you import each and every mesh yourself, but you lose textures and animation
    (and other properties) associated with the mesh.
    Importing a complete model/scene: This gives you less control, but it imports a complete scene with all its properties.
    Importing a Mesh
    As soon as you add an .obj file to the Godot project directory, it will be automatically imported. A scene in which your mesh resides will be
    created. In the case of the simple cube, it looks like the one in Figure 13.4.
    FIGURE 13.4
    A scene containing the cube node. The cube is black because there is no light source, only a mesh.
    If you’re not happy with the way your mesh was imported, you can select it in the FileSystem window and open the Import tab (next to Scene).
    There, you can change settings and click “reimport” (Figure 13.5).
    FIGURE 13.5
    The reimport window. It also works if you select multiple files of the same type.
    111111111
    22222222One disadvantage is that the automatically created scene cannot be edited. You have two options to fix this:
    If you double-click the scene to open it, it will warn you and give you the option to create a new inherited one.
    Right-click an existing node (in a different scene), and choose
    Merge fromScene. Locate the .obj scene, click the cube node, and
    click “OK.”
    As you might have noticed, the mesh of our 3D model is displayed by a
    MeshInstance node. This is always the case—every single mesh
    needs a single
    MeshInstance node.
    NOTE
    MultiMeshes
    The
    MeshInstance is quick and powerful, but if you’re using hundreds or thousands of instances of the same mesh, it will severely affect
    performance. For this, look at the
    MultiMesh node as the solution.
    Importing a Model/Scene
    Importing a scene uses the same process, just a different file format. The file format to use is .DAE. Unfortunately, some software has a really
    broken export system for this, which you must first fix:
    Maya/3DS Max: uses “OpenCollada” plugins.
    Blender: On the Godot website, under downloads, you’ll find a “Better Collada Exporter.”
    Once you have your scene exported, add it to the folder of your Godot project, and it will automatically import. Below is a scene with three
    cubes. Notice in Figure 13.6 how Godot also imported the light, the camera, and an animation player.
    FIGURE 13.6
    A complete scene, imported automatically.
    Note: A new standard asset exchange format called glTF has been released. It has significant advantages and will replace Collada in the near
    future.
    3D Editor
    Now that we have something in our scene, let’s see how we can move around our 3D world and change the view.
    First, it’s important to be in the 3D editor view. You can get to the 3D view by clicking the word “3D” at the top, pressing the F2 key, or selecting
    any 3D node in the Scene view.
    Moving the Camera
    It’s very important to be able to move the camera around easily. It saves you a lot of time, and it allows you to quickly move around the scene
    and look at objects from all angles. The default controls are as follows:
    Zoom in/out: scroll wheel
    Orbit around selection: middle mouse button + drag
    Pan left/right/up/down: shift + middle mouse button + drag
    If you don’t like these controls, you can change them to a different popular configuration in the editor settings (Figure 13.7).
    FIGURE 13.7
    The 3D editor settings. There are many properties you can change are not covered in this lesson.
    Changing Camera View
    By default, the editor camera is in perspective view (as can be seen in the top-right corner of the view). Sometimes, however, it’s more useful
    to look at the world in 2D to see if things line up perfectly.
    To do so, click on the “Perspective” text, which opens a window.
    FIGURE 13.8
    The camera view list. Every view is quite self-explanatory; the top view, for example, views the world as if the camera were watching it from
    above. In this list, one can also turn on/off certain visuals within the editor.
    Additionally, we can also split the screen into multiple views. To do so, click the “View” button to get the following dropdown list:
    111111111
    22222222FIGURE 13.9
    You can split the screen into up to four viewports. It’s common to set the top-right viewport to perspective and the others to top, left and front.
    This ensures that you can see the scene from all sides. You can also turn on/off the origin lines and the grid.
    Transforming Nodes
    You probably already noticed that, in 3D view, there are circles and arrows drawn around an object. These are called gizmos, and they can
    help you translate, rotate, and scale the node quickly. They do not show up in the final game.
    To use a particular gizmo, hover over it with your mouse until it turns white, then click and drag it.
    Gizmos are nice, but sometimes they can be in the way, especially if you want to transform only one element (such as scale). To switch to a
    singular transformation mode, use the buttons on the upper left.
    Of course, if you know exactly how many units you want to translate/rotate/scale a node, you can simply edit the number in the properties of the
    node in Inspector.
    Cameras
    We’ve thus far learned everything about placing objects in our scene and working within the 3D editor. However, if you only have 3D models in
    your scene, you would see nothing when you started the game! Without a camera in the 3D world, there’s no way to show the world, because
    the engine doesn’t know from which angle and distance to view the world.
    FIGURE 13.10
    Gizmos displayed around a cube.
    FIGURE 13.11
    From left to right: default setting, only translation, only rotation, only scaling.
    Creating a Camera
    To put a camera into the world, we use, not surprisingly, the
    Camera node. Make sure you don’t accidentally choose the Camera2D
    node.
    The new camera will be instantiated at the origin, and you can move it around and rotate it using gizmos. To preview what the camera sees,
    press the
    Preview button at the top right of the editor view.
    Camera Settings
    Like every node, the camera has important properties that can be edited in Inspector.
    FIGURE 13.12
    The main camera settings.
    The projection property has two options: perspective and orthogonal. The perspective type is the default type, with objects getting smaller as
    they are further away. With orthogonal projection, sizes stay the same, and you basically convert a 3D world to a 2D one on the screen.
    The fovy property stands for “field of view,” and determines how much the camera is zoomed in. What’s the difference with moving the camera
    closer? By increasing the field of view, objects get “warped” around the edges of the screen, as if you’re applying a fisheye effect. On the other
    hand, decreasing the field of view gradually turns a perspective camera into an orthogonal one.
    The near and far properties determine how close and how far the camera can see. For example, if you have a camera following a player, you
    might want to cut away all objects closer to the camera (than the player) to have an unobstructed view.
    Lastly, we have the very important current property. To understand what it does, we must first learn about viewports.
    About Viewports
    Every camera must answer to a viewport. Look at it this way: The camera registers part of the world, then hands this picture over to the
    viewport, which is responsible for actually displaying it on the screen.
    The root node of every scene is automatically a viewport. Godot does this for you, so our current camera, a child of the root node, has a
    viewport. Because it’s the only camera, everything works as expected.
    If we added another camera as a child of the root node, we’d run into problems. A single viewport can only display the picture from a single
    camera, so we have to choose. This is where the current property comes into play. By setting the current property on a
    Camera node to
    “on,” it becomes the active camera for its viewport.
    Below is an example script that switches to a different camera when the game starts.
    LISTING13.1 Camera Switching
    111111111
    22222222Click here to view code image
    func _ready():
    $Camera.set_current(false)
    $CameraTwo.set_current(true)
    Working with Multiple Cameras
    There are cases, however, where you want to use multiple cameras at the same time; for example, in a split-screen game or when you want to
    display a minimap. If that’s the case, you’ll need to add your own viewports for each camera.
    This is discussed in great detail in Hour 21 (“Viewports and Canvas”).
    Manipulating the Camera
    Most likely, you won’t have a static camera. The camera will follow your main player, or, as often seen in strategy games, the player can freely
    move the camera around the map.
    The easiest way to make the camera follow the player is to make the
    Camera node a child of your
    MeshInstance node. However, this
    is also very restrictive and results in jagged movement, as the camera follows exactly what your player is doing.
    A better way is to control the camera with code. Here’s an example of how to make the camera follow a node called Cube from a safe
    distance. (This script should be placed on the parent node of the camera and cube.)
    LISTING13.2 (Very) Simple Camera Follow
    Click here to view code image
    extends Spatial
    func _process(delta):
    $Camera.set_translation($Cube.get_translation() + Vector3(0, 25, 25)) # offset
    the camera from the cube
    $Camera.set_rotation(Vector3(-45,0,0)) # rotate it so it faces the cube
    As you can see, in 3D, we work with Vector3(X,Y,Z) instead of Vector2(X,Y). Also as expected, get_position() becomes
    get_translation(), and all 3D functions accept Vector3 arguments only.
    If you test this code, it will work, but it will still feel choppy. Luckily, Godot offers an alternative to the
    Camera node, which is the
    InterpolatedCamera node.
    Interpolated Camera
    The
    InterpolatedCamera node is the same as a regular camera, but with a useful addition, which you can see in Inspector.
    FIGURE 13.13
    The extra properties for the interpolated camera.
    You can set a target node, and it will smoothly follow the node wherever it goes. So if the node abruptly moves, the camera will interpolate
    positions and slowly move with it (instead of jumping around).
    There’s one important pitfall: the
    InterpolatedCamera node moves to exactly the location of the target node, instead of following from a
    distance. So it’s best to set a
    Position3D node as the child of the cube, offset it by a certain distance and make it face the cube, then use
    that
    Position3D node as the target:
    FIGURE 13.14
    A working configuration for a smooth camera follow.
    In the end, it depends on what kind of camera behavior you want. The
    InterpolatedCamera node provides a quick and easy way to get a
    smooth camera follow, but it’s highly likely that you’ll need something more advanced or unique. In that case, you can just use a
    Camera
    node and script the desired behavior yourself.
    Summary
    In this hour, you’ve learned about the spatial node, and how to recognize and use 3D nodes. You’ve learned how to import 3D models and
    meshes into Godot and use them in a scene. You’ve learned how to navigate around the 3D world, and how to make the most of the 3D editor.
    Finally, you’ve learned how to create and set up cameras, what to do with multiple cameras, and how to script camera behavior.
    Q&A
    Q. Can I use 2D nodes in a 3D game?
    111111111
    22222222A. Yes, 2D nodes can be used, and they will be fixed to the camera screen. Obviously, you can use all
    Control nodes, which are 2D by
    nature, for the GUI of your game. Other 2D nodes, such as the
    TouchScreenButton, work exactly the same in 2D and 3D, and
    should be used in both. But besides that, most 2D nodes should be replaced by a 3D counterpart or a GUI node. And some nodes simply
    don’t do anything in 3D, such as the
    Camera2D node.
    Q. How do I detect what’s under my mouse in 3D?
    A. In 2D, if you want to check if a Sprite was clicked, you can just use an Area2D and signals that check whether the area was entered or
    exited.
    As you might have guessed, it’s not so simple in 3D. Usually, raycasts are used, which are invisible lines shot from the camera toward the
    3D world. These raycasts check whether the line is obstructed by any object. They are too complex to discuss here, but remember them,
    as they are very useful.
    Q. Help—my object doesn’t rotate the way I want it to!What do I do?
    A. 3D rotation is a tough subject. If you rotate multiple axes at the same time in the wrong way, you could get something called “gimbal lock.”
    It’s a transform configuration in which you suddenly lose a degree of freedom and can only rotate around two axes. Usually, people resort
    to other rotation measures, such as quaternions or using the transform matrix that was covered earlier.
    Workshop
    Now that you have finished the hour, take a few moments to review and see if you can answer the following questions.
    Quiz
    1. Which three fundamental actions can you perform on any 3D node?
    2. One can switch to the 3D editor by pressing the key.
    3. Which axis points upward inGodot?
    4. True or False: Importing inGodot happens automatically when you place a file in the project folder.
    5. True or False: A .obj mesh can also contain other elements, such as lights and cameras.
    6. True or False: You can only have a single camera per viewport in a 3D scene.
    7. True or False: The
    Camera node automatically smoothens movement.
    8. Which data type should be used to contain 3D (X, Y, and Z) data?
    Answers
    1. Translate, rotate, and scale.
    2. F2.
    3. The y-axis.
    4. True. You can, however, choose different settings and reimport if you want.
    5. False. A mesh contains only a single 3D object, while a .dae scene contains everything.
    6. False. You can have multiple cameras per viewpoint, though you need to choose which one you want to use by setting the current property.
    7. False. You need to script that yourself or use an
    InterpolatedCamera node.
    8. The Vector3(X,Y,Z) data type.
    Exercises
    In this exercise, we will be creating a 3D “city” and writing a script that allows the camera to navigate it, just like in a city-building game.
    1. Go to your favorite 3D-modeling software and create something that vaguely resembles a (small) city. Use cylinders, cubes, and
    pyramids to create simple buildings.
    2. Import your creation into Godot. Make sure you allow the individual buildings to be edited one way or another.
    3. If not already in the scene, add a light so that you can see the city well.
    4. Add a camera and point it toward the city. Attach a script to the camera so that it moves left/right/forward/backward when you press the
    arrow keys on the keyboard. (Bonus points if you can make that movement smooth.)
    5. Allow the camera to zoom in/out when the user scrolls his mouse scroll wheel.
    6. BONUS: Create an animation for a building that makes it jump up and down. Start this animation when the camera gets within a certain
    distance of this building.
    7. BONUS (hard): Write a script so that every building within the vicinity of the camera starts jumping up and down. (I don’t recommend an
    animation for this, but rather using code to make buildings jump.)
    Bonus Exercise: We’ll be creating a very simple racing game.
    111111111
    222222221. Create a simple 3D mesh (such as a cube), and import it in to Godot. This will be a car.
    2. Duplicate this mesh a few times and number each logically.
    3. Attach a camera to each car and make sure each camera follows its own car.
    4. Write a script that keeps track of which car you’re currently controlling. When you press a certain button (say, “K”), it should switch to the
    next car.
    5. In the same script, add an input handler. Write code so that the car you’re currently controlling (and _only _that car) responds to the arrow
    keys for movement. For the best visual results, rotate the car in the right direction. (In such a simple environment with few reference
    points, it can otherwise be hard to tell where your mesh is actually going.)
    6. Now you should be able to control one car at a time and jump from car to car by pressing the “K” button.
    111111111
    22222222