Setting up a 3D menu in Unreal Engine is easy as pie. That makes your game even more attractive. Let me show you how to do it.
With the release of Unreal Engine 4.13 a new bunch of amazing features became available to us fellows’ developers. Obviously out of all these new features, one that could not go unnoticed is the amazing Widget Interaction Component. I can’t think of a better use of such feature rather than implementing a 3D menu. Furthermore, we all know how important menus are in video games if well designed but mostly if gorgeous and attractive. We are going to setup a very basic 3D menu together, let’s go over what the menu will support:
- The player will be able to toggle the menu on and off.
- The menu will appear in front of the player whenever toggled.
- The player will interact with the menu using a gun.
Without bubbling any further let’s get to the fun.
The very first step to take is making sure that you are running on unreal engine 4.13. Open Epic Games and in the Unreal Engine tab check that the version you are launching is 4.13.
If you haven’t downloaded the new version yet, click library and click on add version.
Once you have unreal engine 4.13 installed launch it and we can move onto step 2.
Create the project and widget interaction component
Create an empty project by selecting the new project tab and under the blueprint tab choose First-Person template. Name the project whatever you want it to name and then click on Create project.
Now that we have our project ready let’s go ahead and set up our widget component. In the content browser go to “FirstPersonBP\Blueprints” and open the “FirstPersonCharacter” blueprint. Go to the left panel called Components and click on Add Component in the search box type Widget Interaction and click on it.
The widget interaction component will be now displayed in the Components panel at the bottom of the components list. Drag the widget interaction component onto the sphere component parented to the FP_Gun and then release it. This will parent the widget interaction component to the gun. Lastly compile.
Next select the widget interaction component from the components panel. Once it is highlighted the details panel on the right will be filled up with all the relevant details about the widget interaction component.
Go under the Transform tab in the details panel and zero out the location of the component. Then enter the following values for its Rotation: X = 0.0º, Y = 1.5º and Z = 9.0º. In the details of the widget interaction component you’ll see a tab called “Interaction”, look for interaction distance, set the value to 1000. If you want to check out what this looks like at the moment you can momentarily tick the Show Debug box and play simulate, however we’ll toggle it on and of later via code.
The Blueprint Widget Holder
The next step is to create a basic blueprint class which will hold our widget, this blueprint is necessary for the widget to be spawn in a 3D space. Go ahead and in the content browser either right click in an empty area or click on add new, then select blueprint.
You’ll be presented with a window that allows you to choose the parent class you want your blueprint to inherit from. From the list presented choose actor, lastly name this class whatever you prefer I’ll name it “ExampleWidget”. Bring up the newly created blueprint by double clicking on it and in the Components panel click on add component then type and select widget. Finally compile and close the blueprint.
Create the widget
Now that we have a blueprint capable of containing our widget we’ll have to create a widget. In the content browser either click on an empty space or click on Add New, in the menu under “Create Advanced Asset” scroll down to User Interface and from the item’s list select widget blueprint.
You can name your widget whatever you feel like, I’ll name it interactive widget. Go ahead open the widget and add inside it at least one element, the widget can contain whatever you want it to contain, for the purpose of this tutorial it doesn’t matter whether it is a complete menu or just one button.
Spawning the Widget
Once the widget is ready, go back to the example widget blueprint we created previously, the one that should contain our widget. From the Components panel on the left select the widget component and in the details panel navigate to the User Interface tab, the second option from the top is Widget Class. Use the drop-down menu to select the widget you just created.
Go back to the example widget blueprint and in the event graph set the following nodes.
What we are doing here is setting the widget component of the blueprint to have no collision and being hidden as the game starts.
Following let’s head to the “FirstPersonCharacter” blueprint and create a variable of type example widget reference called “Example Widget” and click the little eye icon on the right of the variable, this way the variable will be public, finally compile. In the World Outliner select the FirstPersonCharacter this will bring up a whole bunch of properties related to the blueprint in the details panel below, type in the search bar example widget and under the default tab set the variable to the Example Widget blueprint.
Go back to the FirstPersonCharacter blueprint and build the following.
What we are doing here is choosing an event key for toggling on and off our example widget class. The way this happens is by checking if whether the widget component of the example widget blueprint is visible in the scene, if it is we use again the exact same nodes we used earlier on the example widget blueprint “Event BeginPlay” therefore we hide it and we set the collision to no collision, else we set it to be visible and set the collision to “Query Only (No Physics Collision)”.
Prevent character from shooting
In the FirstPersonCharacter blueprint let’s create a Boolean variable called “Menu Active” to use as a flag. We’ll set it to false when we hide the widget and to true when we make it visible.
Following let’s make some use of menu active, inside the “Spawn Projectile” commented section, out of “InputAction Fire” drag a pin and add a branch of which the condition will be set to the value of “Menu Active” then disconnect the true pin and connect the false pin to the “Montage Play” node. In this way we’ll only be able to fire if the menu is off.
Somewhere in the FirstPersonCharacter blueprint build the nodes illustrated below.
All these nodes are doing is binding the left mouse button to the widget interaction event, in doing so the widget will interact with the debug line whenever the left mouse button is pressed.
Lastly, add the following three nodes to the blueprint.
Spawn the widget at the right location and rotation
Now that our menu toggles on and off we have to do something to make it appear in front of us at the right rotation. In the FirstPersonCharacter blueprint on the branch that toggles on the menu add the following nodes.
What we are doing in this part is setting the widget location and rotation, the location is set to the be the location of the first person actor with its up vector and forward vector multiplied by some float value (you can use any value that you feel are right for your scenario and necessities). This allows to set the widget location to be the same as the first-person location with an offset on its forward vector and up vector by some values. Next, we set the rotation of the menu by using the node “Find Look At Rotation”, out of the returned rotator we only need to use the X(Roll) and the Z(Yaw) hence we break the rotator and make a new value containing only X and Z.
Lerp from current rotation to looking forwards
For the next step we’ll need a custom while loop with delay, go ahead and build a macro like the one at the bottom.
Once the macro is ready create two new variables called “deltaTime” (float) and “ResetPosition” (Boolean). After the “SetActorRotation” node set the newly created “ResetPosition” to true as shown in the next screenshot.
Following, somewhere in the blueprint build the below structure.
What we are doing here is checking if the menu is active and we want to reset our rotation, if it is the case then we use the macro “WhileLoopWithDelay” to interpolate from our current rotation to a new rotation which retains our Yaw but sets to zero our Roll and Pitch. Once “RInterp To” is finished we set the variable “Reset Position” back to false.
Prevent the character from moving
Under the commented section “Movement Input - …..” add two branches after the events “InputAxis MoveForward” and “InputAxis MoveRight” so to check if the MenuActive variable is set to true, only if it’s set to false we want to allow “Add Movement Input” to work.
Add the menu boundaries
The last step we have to take is creating the menu boundaries. The first thing to do is making some variable namely the following: “AxisTurn” (Float), “AxisLookUp (Float), “CompareVector” (Vector), “CurrentVector” (Vector), “GunCompareVector” (Vector) and “GunCurrentVector” (Vector).
After the “ResetRotation” Boolean we set earlier add the following nodes.
This will give us the current right vector of our mesh and the current up vector of our gun offset by 30 units on the Pitch. We store these two variable in “CompareVector” and “GunCompareVector”. Next grab the commented section “Mouse Input” move it somewhere in the blueprint and make it way bigger.
How it works
In “InputAxis Turn” we firstly check if the menu is active if not we normally feed the “Add Controller Yaw Input”. Otherwise we store our current right vector into “Current Vector”. Next we make use of the “CompareVector” previously assigned and the “CurrentVector” by normalising them and computing the Dot Product. Successively we check if the value is less than 0.9.
If that is the case it means that we are trying to go over our boundaries. We want to know if we are going to the right or left, and to do so we normalise “CompareVector” and “CurrentVector”. Then this time we compute the cross product from which we break the vector returned.
We grab the Z value of the broken vector and check if the value if more or less than zero. If it is less than zero and we are trying to go to the left, we don’t do anything. Otherwise we feed the “Add Controller Yaw Input”. On the other hand, if the Z is more than zero and we are trying to go to the right we don’t do anything. Else, we feed “Add Controller Yaw Input”.
The “InputAxis LookUp” is exactly the same with the only difference that once the dot product is computed we check if the return value is more than 0.9 or less than 0.3. This is possible since we offset the “GunCompareVector” by 30 unit on the Pitch.
With the previous step over, the 3D menu is now ready to be tested, go ahead and try it out. I'd obviously like to point out that the system is far from being perfect. There are many edge cases that are not covered hence you are most likely to encounter bugs while testing it. This is just an extremely simple example which I hope will help you to start off.
I hope you found this article helpful and if by any chance you run into troubles you can always refer back to my YouTube video.
If you have any questions on something you may not have understood please leave a comment.