Cameras & Character Controllers



One of the very first things you need to create in any 3D game is a camera control system, or way to move a character around the scene in response to input. In this chapter, we are going to look at both topics, first by looking at how you can control a camera using both logic nodes and then using Haxe script. We will then look at using a preconfigured logic node to handle both our camera and character controls.

First, let’s look at controlling the camera using nodes. We already explored the camera briefly in the last Armory3D tutorial where we created a custom node for controlling the active camera. Your scene should always have at least one camera object in Blender, although Armory will now create one if none are defined. We can get a reference to the active camera using the node Active Camera.

Cameras & Character Controllers

If you have more than one camera in your Blender scene, you can choose the active camera by selecting it, then in the 3D View select Cameras->Set Active Object as Camera.

Cameras & Character Controllers

There are only three built-in camera nodes, Active Camera that we saw moments ago, as well as Get Camera Field of View and Set Camera Field of View.

Get Camera Field of View Armory3D

Using these enables you to essentially zoom in and out your camera. Let’s look at a controller that increases and decreases the field of view when with the left or right mouse buttons held down. Create the following node hierarchy:

Node Hierarchy - Camera & Character Controllers

In this case, when either button is held down, we get the current field of view, either add or subtract 0.01 from it, then set the active camera’s field of view using the newly updated value. Here is our code in action:

Code in Action - Armory3D

Now let’s look at panning the camera in all four directions. We will once again be using the trust Translate on Local Axis node to move our camera left and right. Repeat this sequence for the up and down arrow keys this time with Forward/Up/Right set to 1.

Translate on Local Axis - Armory3D

Finally let’s wire up the 1 and 2 keys to orbit the camera around the z-axis, like so:

Camera Orbit - z-axis

As you can see, controlling the camera is the same process of controlling just about any other node.

Now let’s jump over to Haxe land and implement a basic camera handler as a Trait. Create a new Trait and attach it to the camera in the scene. This particular example assumes that the camera left/right is the X-axis and up and down is the Z-axis. Here is the code:

package arm;
import iron.object.CameraObject;

class CameraControls extends iron.Trait {
  public function new() {
    super();
    var mouse = iron.system.Input.getMouse();

    notifyOnInit(function() {
      mouse.lock();
    });

    notifyOnUpdate(function() {
      var camera = cast(object.getChild("Camera"),CameraObject);
      

      if(mouse.down("left")){
        object.transform.loc.addf(mouse.movementX * 0.01,0,mouse.movementY * 0.01);
        object.transform.buildMatrix();
      }
      if(mouse.wheelDelta != 0)
        camera.data.raw.fov += mouse.wheelDelta * 0.01;
        camera.buildProjection();

      if(iron.system.Input.getKeyboard().down("esc")){
        mouse.unlock();
      }
    });
  }
}

In this example in the init function we call lock() on the mouse, this traps the mouse to the constraints of the screen. You will notice later on in the update callback, we unlock the mouse if the user hits the Escape key by calling predictably enough unlock(). Otherwise, we check to see if the user holds down the left mouse button and if they do we move the mouse along the X and Z axis relative to 1/100th of the amount the mouse was moved. Notice after we modify the location, we call buildMatrix() so the updated transformation matrix is created. The other portion of this demo is where we check to see if the mouse wheel has been scrolled, which returns a value of either -1 or 1 depending on direction. In the event the mouse wheel is moved, we zoom in or out by updating the fov(field of view). After making this change we need to rebuild the projection matrix using buildProjection().

That is the extent of the Haxe code we are going to be looking at today, but do be aware there are two built-in traits FollowCamera and FirstPersonController, which are great ways to understand how to manipulate the camera using Haxe.

Now let’s tie it all together (plus a bit of what we learned in the last chapter!) by using the community provided camera controls from the Logic Pack. Start off by creating a folder called Libraries in the directory where your scene’s .blend file exists. This next command assumes you have a git client installed and configured. If you don’t have git installed you can get a free client here.

In a command prompt or terminal, CD into your game project folder, then CD into the newly created Libraries folder. Then run the command:

git clone https://github.com/armory3d/logic_pack

Like so:

Command prompt

If your Blender file is currently open, close and re-open it. Now in the Logic editor, you will have new options, Player Controller and Camera Controller:

Player Controller and Camera Controller

If these nodes don’t show up make sure you created the proper folder structure, the name MUST be Libraries. We then wire up the following simple control graph of nodes:

Simple control graph of nodes - Armory3D

There is also a Player Controller that will handle the movement of your player through the world. This enables you to easily provide WASD style keyboard movement through the game world with settings such as running and jumping while handling mouse look functionality using the Camera Controller. Here is an extremely simple configuration, hooking up the WASD keys to move our camera:

WASD keys Camera Controller

Scroll to Top