30. UE: How to handle zoom and rotate using camera properties

30. UE: How to handle zoom and rotate using camera properties

In this post we’re going to cover some more zoom and rotate options, this time without the use of a spring arm. Here are some alternatives:

If you’re interested in how you can use the spring arm version, you can find the details on this post.

In this post we will cover:

  • Object that we will want to rotate in our view using left mouse button click (can bind to other buttons)
  • Zoom in and out with smooth limits using mouse wheel
  • Move camera field of view using right mouse button (can bind to other buttons)

Let’s get started with rotating the object, in this post we should have a ‘simpler’ version than the one covered in part 15. Check out video demo here.

handle rotate and zoom of camera and object

Reference the rotating object in Player Controller

Pretty much all of the code will sit in our player controller class. This is somewhat optional – though if you’re using Character as parent its not as Character will consume inputs that you don’t want.

Open up the blueprints for the object that you wish to rotate, it should support any type (which is why I made changes from part 15, which did not work on Character classes).

The highlighted parts is what you will want to add to your object blueprints:

In my blueprints, I will not always want it to be rotated, which will be controlled via boolean variable – feel free to do something similar in your project if you want to sometimes disable it.

Init Rotate and Zoom has not been created yet, so let’s get started with that – you can create new graphs to store and separate this logic.

The Init custom event can go inside the BindRotateZoomEvents graph.

Inside your Player Controller class, let’s create the entry point.

The first thing that you will want to do is make a reference of the object that you will want to rotate.

You can do this either by adding input to your custom event and making reference to self from your caller object, or simply Get actor of class like I have and referenced the class I desire to rotate.

Do note that this will only support 1 object in your map to rotate.

If you need to support more rotating objects, you will want to do the rotation inside the object code itself, like in this post.

So note, the Character Proxy class is the object I will be rotating in the map.

I iterate over all objects because the proxy character is destroyed and recreated when you traverse between different screens (character create / select screen).

This means that sometimes the actor will still exist, but is not valid as its pending to be picked up by garbage collection.

Update rotate and zoom on timer ticks

After determining the object that will be rotated, we can setup our timer events

Set timer by event will allow us to call a custom event every 0.03 seconds in this setup. We can use update tick instead if you prefer.

Create the booleans zoom in progress and rotate in progress booleans which will be true when we’re left/right clicking and dragging our mouse, otherwise they remain false.

On each timer tick, we’re going to do the following:

  • update mouse drag and store it in variables, for left and right mouse buttons
  • evaluate the zoom angle required for the lens
  • adjust camera rotation (based on right mouse drag)
  • adjust object rotation (based on left mouse drag)

Before we go into each function, let’s see what else is referenced on this graph.

Input mappings

Here we map the left mouse click will update previous location X (we don’t need Y for rotating object, but can map that too) as well as setting rotate in progress to true.

We also map the right mouse button which will update both X and Y co-ordinates as well as setting zoom in progress to true.

We also map the mouse wheel up/down which will control the zoom – we do this by increasing/reducing the zoom velocity variable, which we will process in a function that we’ll create shortly.

In order to map these inputs, click Edit -> Project Settings -> Input

This is how mine were defined, you can map to whatever keys you like.

Update drag

Getting drag is essentially getting the delta of the X and Y axis from last time it was executed.

That’s what this function does, we have a variable PrevLocX and PrevLocY storing the values of X and Y from previous iterations. Then we get the current X, Y co-ordinates and get the difference between them.

Evaluate and set zoom

Feel free to add new graph for zoom/rotate work, this is optional but could keep your work more tidy.

Let’s look into Evaluate and set zoom

Zoom is essentially the field of view – this is stored in a float variable.

The Evaluate Field of View function is specifically to evaluate what the value should be.

After we do so, we simply take our camera component and set the field of view to processed one (default camera is setup in few steps ahead).

In order to achieve smooth zoom in/out, we will use curves.

If the zoom velocity is positive, we use zoom in curve, if velocity is negative, we’re zooming out, therefore using zoom out curve.

After the processing, we will apply a small decay to the velocity (the multiplication by 0.9), which will ultimately bring it down to 0 with time.

Zoom curves

We want the minimum angle for camera lens to be 15 degrees and maximum 90 degrees.

The higher the angle, the more zoom we achieve. Do note for distortion as the angle becomes too high or too low.

The zoom in curve is used as a multiplier, which basically smoothens the zoom between 0 and 1 (0 means it will not zoom).

The zoom in curve is as follows:

The first point is 15, 0 as highlighted and the second is 90, 1 with auto tangents between them.

This means that as we zoom it will get less effective as you approach max zoom (at 15 degrees). Remember, the smaller the angle, the larger the zoom.

With zoom out curve, its essentially the opposite.

There are two keys again, first at 15, 1 and second at 90, 0. So as you zoom out, you will go from 15 degrees up to 90 degrees (max) at which point the multiplier drops to 0.

Process Field of View

Before we process the field of view, let’s first reference what it is that we’re changing.

In your map you can have your camera defined like this:

Field of view of camera

You can see the field of view parameter is defined in the details of the camera. It’s essentially the camera lens that’s used.

Its up to you how to get the default camera variable from your player controller, I set it up in the construction of Player Controller blueprint using this:

Now that we have access to the camera and we know what the field of view parameter is, let’s process field of view.

Here we extract the current field of view of the camera and we get the float value from the curve which can be the zoom in/out curve.

If the camera field of view is currently almost 90 degrees and we’re trying to zoom out more – the multiplier will be basically 0 which means even if we’re adding velocity through our mouse wheel up/down, we’re not going to zoom out further.

Its basically the same for zoom in, with minimum allowed value of 15 degrees.

We then add the ‘zoom velocity’ (positive or negative) to current field of view and that’s how we get the resulting field of view.

That’s all for the Evaluate and set zoom function.

Adjust camera rotation

This is the next function after evaluating and setting zoom.

This custom event is responsible to evaluate the camera rotation velocity then apply it to the camera, after which reduce the overall velocity of rotation.

Let’s look inside ProcessCameraRotatorVelocity

This function will take the drag that we’ve evaluated earlier and convert it to velocity based on a multiplier. If you want to invert directions, you should add that here.

We will only add this if the right mouse button is clicked, i.e. the zoom in progress boolean is true.

Next, let’s look at the RotateActor function.

This is quite simple, we just take the reference of the actor and set actor rotation.

Do note that Add actor rotation should work, but for some reason it has some bugs, adding rotation to axis that had 0’s in. So perhaps in future versions of UE it should be fine.

That’s it for camera rotation! Let’s check the character rotation next.

Handle character rotation

This is the last piece from the tick event

This functionality also lives inside the Handle Rotate graph, but feel free to put it in separate graph.

This custom event evaluates the rotate speed. Note the passed in argument of delta seconds – you can add it like this or just keep it as custom sensitivity parameter inside the function nested inside.

The HandleRotateHorizontalDragEvent is as follows

We only process the object rotation velocity if the Rotate in progress is true, i.e. the left mouse is pressed.

The process and set rotate velocity function essentially converts the drag into rotation velocity with some multipliers. Here is where the delta time is used – note that it can simply be a static variable.

The rotate actor function was the same one used for rotating the camera.

Again, note that add rotation function may not work as expected – but feel to try it yourself.

And that’s it!

We now completed:

  • zoom in/out with camera lens
  • move camera field of view (rotate camera)
  • rotate object

Good luck!