Following a character with ChaseCamera

In this recipe, we'll explore jMonkeyEngine's ChaseCamera class. This camera is a bit different from the previous cameras we've explored since we don't have direct control over its position. It is not like the camera-on-a-stick method we tried in the Creating a reusable character control recipe. While it still follows and looks at the character, it can float around the character more freely and also be controlled by the player.

The default control for the camera is to hold down the left mouse button and drag it to rotate the camera around the character. This is a very common control pattern in third-person games on consoles, where you rotate the camera with the left stick and control the character with the right.

We will implement a behavior where the character moves in the direction the camera is facing rather than the direction the character is facing when you press the forward key. This is common in console games.

Getting ready

Out of convenience, we'll extend, or modify, the GameCharacterControl class from earlier. This way, we'll get some of the basic functionality and save some time.

How to do it...

To start off, we can create a new SimpleApplication class in which we'll apply the following steps:

  1. To initialize the camera, you supply the application's camera, spatial, to be followed, and the input manager, as follows:
    ChaseCamera chaseCam = new ChaseCamera(cam, playerNode, inputManager);
  2. The ChaseCamera class has lots of settings to suit different kinds of games. To start off, we turn off the need to hold down the left mouse button to rotate the camera. It's not something we want for this recipe. This is implemented as follows:
    chaseCam.setDragToRotate(false);
  3. We do, however, want smooth movement for the camera. For this, type the following line of code:
    chaseCam.setSmoothMotion(true);
  4. By default, the camera will focus on the origin point of spatial, which in this case, would be Jaime's feet. We can easily make it look at a higher-up point, such as waist.chaseCam.setLookAtOffset(new Vector3f(0, 1f, 0));.
  5. Next, we set some distance restrictions for the camera. There is no guarantee that it will stay within those boundaries though. It especially seems to violate minDistance:
    chaseCam.setDefaultDistance(7f);
    chaseCam.setMaxDistance(8f);
    chaseCam.setMinDistance(6f);
  6. The ChasingSensitivity method defines how quickly the camera will follow spatial. If it's 1, it will follow slowly and if it's 5, it will follow quickly. We want the camera to be pretty responsive in this recipe:
    chaseCam.setChasingSensitivity(5);
  7. The following RotationSpeed method defines how quickly the camera moves when moving it:
    chaseCam.setRotationSpeed(10);
  8. Now, we have a basic setup for ChaseCamera. Let's see what we need to do to the GameCharacterControl class to suit this kind of game.
  9. We can easily apply the behavior where forward is the direction of the camera by replacing the two lines, and setting modelForwardDir and modelLeftDir in the update method:
    Vector3f modelForwardDir = cam.getRotation().mult(Vector3f.UNIT_Z).multLocal(1, 0, 1);
    Vector3f modelLeftDir = cam.getRotation().mult(Vector3f.UNIT_X);
  10. Since we don't directly control the characters' view direction anymore, we can set it to always be the last direction the character faced (when moving) as follows:
    viewDirection.set(walkDirection);
  11. At the end of the method, we mustn't forget to apply it to PhysicsCharacter as follows:
    setViewDirection(viewDirection);

How it works...

The ChaseCamera class is a convenient class that offloads a lot of camera handling from the coder. It has a lot of settings that can be tweaked to get the desired behavior. Camera tweaking is a delicate and time-consuming matter, and if you're working in a team, this is something a designer might do if the properties would be exposed in a text file and loaded during startup.

There's more…

If you press forward and then rotate the camera, the character will move in that direction, instead. In many games of this type, however, the character would keep running in the direction it had before the player rotated the camera. We can apply this behavior to our character with a few tweaks.

To do this, we need to change modelForwardDir and modelLeftDir into private fields in the class. Then, we make sure we only update these when the character isn't receiving any input from the player. In this recipe, this would mean an if statement, as follows:

if(!forward && !backward && !leftStrafe && !rightStrafe){
  modelForwardDir = cam.getRotation().mult(Vector3f.UNIT_Z).multLocal(1, 0, 1);
  modelLeftDir = cam.getRotation().mult(Vector3f.UNIT_X);
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.93.141