And Half A Fish Games.

And Half A Fish
Games

UE4 code. Jan 30, 2017 - Old school style navigation for a 3D point&click game.

This blueprint code is from a 3D point&click game that I'm currently working on (UE v4.14.3).

For this 3D game, I want the navigation to be limited to left/right, up/down, just like in the old school, pre-rendered Flash games of a long time ago. Something like this (hopefully you can see the mouse move in the gif) :

In-editor demo of navigation system. Setup in the editor : 2 cameras/ 2 views.
Two camera's for the 2 views in the game. The game starts with a view through camA_0.

In an earlier 2D game called 'Finding Fifi', I created a similar navigation system with just one camera. In my current 3D game, I want to use a system with multiple cameras. I'll show you how to do this with just 2 cameras, but the setup is the same with multiple cameras.

First, you need to create a generic camera object. All the cameras in the game will be derived from this one. In other words, all the properties and functions that we create inside the generic camera object will be inherited by the camera 'children'.

Actor blueprint in content browser. So, right-click inside the content browser and add a blueprint of type Actor. I named it 'bp_camA' (for 'Actor'). Double-click the new blueprint, and in the components tab on the left, add a camera component.

Actor blueprint. Camera component.

Alternatively, you can use a blueprint of type CameraActor (instead of an Actor with a Camera component added).

We only have to do 1 thing in the generic camera object we just created : add 1 variable of type bp_camA for each navigation direction in our game. For example, in this demo, I will only navigate left & right. So, I only need 2 variables :

Variables created in bp_camA. Variable properties.
Create 2 variables inside bp_camA : cam_gotoL & cam_gotoR.

It is important to make both variables 'editable' (eye icon) ; this will later make the variables visible (editable) in the editor (when we place the cameras).

You can now drag & drop the camera actor bp_camA from the content browser into the game scene (as many times as you have views in your game). I'll just create 2 cameras : camA_0 and camA_1.

I also placed 2 objects in the scene, a red ball & a green cube. CamA_0 only sees the ball, camA_1 only sees the cube.
If you now select camA_0 in the scene, in the details panel on the right, you will see the 2 variables that we created for the generic camera object bp_camA. If you can't see them, you probably forgot to make them editable in bp_camA.

If we look through camA_0 (select it in the scene), we can only go left. So, click the eyedropper tool next to cam_gotoL and select camA_1 in the scene. Do the reverse for camA_1 and cam_gotoR.

Setting up the camera navigation system for camA_0.
Setting up the camera navigation system for camA_0.

Next, right-click inside the content browser and add a blueprint of type PlayerController. I named the new blueprint 'myPlayerC'. Double-click myPlayerC and add the following variables (the function will be created later) :

Setting up the Player Controller (1). Setting up the Player Controller (2).

Setting up the Player Controller (3). Setting up the Player Controller (4). Setting up the Player Controller (5).

Now, we need to tell UE4 to look through camA_0 when the game starts. And since this is a point&click game, we'll also need to see the mouse. I have set these things up in the level blueprint :

Setting up camera and mouse in the level blueprint.
Setting up camera and mouse in the level blueprint (click for larger image).

Next, we need to create the navigation widget. So, right-click in the content browser and select 'user interface' > 'widget'. I named my widget 'w_nav' ; double-click to edit. This is the hierarchy that I created :

Creating a navigation widget. Editing the navigation widget.
Creating and editing a navigation widget.

The horizontal box uses the full size of the canvas, and the anchors have been set to the four corners (bottom right panel in the 'anchors' dropdown list). I have set the Z-order to 1, so this widget will always be rendered on top (not strictly necessary in this project).

Navigation widget : horizontal box. Navigation widget : settings for the horizontal box.
Navigation widget : layout & settings for the horizontal box.

These are the settings for the vertical box, used to position the clickable left/right buttons :

Navigation widget : vertical box. Navigation widget : settings for the vertical box.
Navigation widget : layout & settings for the vertical box.

And these are the settings for one of the buttons : make sure to check 'is variable' (top right) for both buttons !

Navigation widget : button layout. Button image. Navigation widget : button appearance overview.
Navigation widget : button layout, button image 'navL.png' & button appearance.
Navigation widget : default style for the button. Navigation widget : mouseOver & pressed style for the button.
Navigation widget : button default style (left) & mouseOver/pressed style (right).

Of course, we also need to define an action for when a button is clicked. So, switch from 'design view' to 'graph view' (top right) and select the left button (left-side panel, under the heading 'variables'). If the buttons aren't there, you probably forgot to make them variables. You will need to do the same thing for the right button.
Next, scroll to the bottom, and still on the left (with the left button selected), click 'onReleased' under 'events'.

Navigation widget - Graph view. Navigation widget : 'button clicked' event handler.
Navigation widget : creating a 'button clicked' event handler.

The code in the event handler is pretty simple.
I usually like to create a variable for my PlayerController in each blueprint. Since there is no 'onBeginPlay' event defined for widgets ('onBeginPlay' fires only once), and button events usually fire more than once in a game, I need to check if I already have a reference to my PlayerController before I make a new one.

Navigation widget - Graph view : 'onReleased' event handler (1).

Still in the 'OnReleased' event handler for btnLeft : switch to the other camera and set it as the 'current camera' in the myPlayerC :

Navigation widget - Graph view : 'onReleased' event handler (2).

We also need to Update the values for the directions the new camera allows us to go in , & the visibility of the left/right buttons in the navigation widget.

Navigation widget - Graph view : 'onReleased' event handler (3). Navigation widget - Graph view : 'onReleased' event handler (4).

Inside myPlayerC, the function fUpdateNav() contains 2 similar blocks of code : one called 'Update navL' (seq.0), & one called 'Update navR' (seq.1). Only the code in 'Update navL' is shown here. We check if the variable 'gotoL' is empty ; if it is, we make btnLeft invisible ('collapsed'). If not, we make btnLeft visible.
The print nodes are for debugging ; you should of course remove them in your final code.

Navigation widget - Graph view : 'onReleased' event handler (5). Navigation widget - Graph view : 'onReleased' event handler (6).

We're almost there !

In the content browser, create a new blueprint of type GameMode. I named it 'bp_gm'. Double-click to edit. Make sure the PlayerController Class is pointing to the PlayerController that you created a bit earlier (myPlayerC). Save, and close.

Create a custom GameMode blueprint (1). Create a custom GameMode blueprint (2).

Last step : goto the World Settings panel, and have GameMode Override point to the GameMode you just created (bp_gm). Save your project.

World settings.

Done !

You're now ready to test, and expand.
Have fun !

PS : If you have a comment, or a suggestion on how to improve these blueprints ... I would love to hear from you !

info[AT]halfafish.be.