Lab Structure
- Labs take place in the classroom. Bring your VR device with you.
- Check Discord for prerequisites.
Submission
Use the following form to submit lab tasks. It is just a shortcut - you don't have to do it again if you have already submitted the task.
Unless clearly specified otherwise, just a screenshot of your Unreal Engine application is needed. Display the viewport and new features that you have implemented. You can add explanations in the comments.
Lab 1 (12.02) - Introduction (Task 1: Experience video editing)
Lab slides are here.
Add a link to the Experience video with the 5 observations that you made to Discord. Use GDrive, Youtube etc. for hosting.
Lab 2 (19.02) - Review and discussion of the Experience videos.
Lab 3 (26.02) - Unreal Engine VR setup / Ball Shooter (Task 2)
Before lab (if needed), enter following command to CMD.exe:
REG ADD "HKCU\Software\Oculus VR, LLC\Oculus\Libraries"
Do the following preparations for the lab:
- Install the Oculus app to your computer (in the classroom 2006 it is already installed).
- Enable Developer mode on your Quest (it will require some steps: https://aixr.org/insights/how-to-enable-developer-mode-on-oculus-quest-2/). After that you should also try to sideload some apps, for example through SideQuest: https://sidequestvr.com/
- Download and install Unreal Engine 5.5 (latest version) - you will first need the Epic Games Account and Launcher - https://store.epicgames.com/en-US/download (in the classroom 2006 it is already installed)
- Try to use the Oculus Link to stream your computer using the provided USB cable.
If you run into trouble, ask help from Discord.
Download Tennis Racket:
Attach:TennisRacket.zip
Source: https://sketchfab.com/3d-models/tennis-racket-c314dcce06ba488ca624957f579b8196
Steps:
- Create a new Unreal Engine 5 project using the VR template.
- Import the tennis racket model,
- adjust its import scale and colliders to work properly.
- add the tennis racket to the Map, make it movable and apply physics.
- turn the tennis racket into a blueprint, give it the grab component, ensure it snaps correctly into the hand.
- Create a ball blueprint similar to the racket using the Unreal's sphere mesh.
- Remove the unnecessary objects from the map and create a Tennis Stadium environment by using the Modeling tools and Cube Grid.
- Create a tennis ball shooter machine:
- Create base and barrel models using the modeling tools.
- Combine both parts into a single blueprint (having two static mesh components).
- Add a script that spawns a ball every second and applies an impulse towards a direction defined by the arrow component (add this component to the point where the balls are thrown).
- Add another script that rotates the barrel continuously using a sine function.
- Make the ball throwing force and barrel rotation arc configurable and test your shooter machine.
- Adjust your parameters so you can hit the balls with the racket.
- Enable continuous collision detection (CCD) for both the racket and the ball to ensure that the hit is always registered.
- Create a ground area blueprint for checking where the balls land:
- Create a static mesh blueprint with a box shape.
- Set its physics to OverlapAll and turn on the overlap events on both the area and ball actors.
- Add a custom event to the VRGameMode blueprint that adds a score to the value and prints it out.
- When the ball touches the ground area call this function in the VRGameMode and destroy the ball.
Now you should have a simple tennis practicing game where you can target a specific area on the ground to gain points. Make a screenshot of your scene in Unreal and submit it as the result of this task.
Lab 4 (05.03) - Immersion and Presence (Task 3)
Making a small table tennis minigame that:
- implements grabbing for the table tennis racket and ball,
- racket has haptic feedback on ball and other surface hits,
- ball has racket and table/other surface hit sounds.
Optional: You can try making the game easier by:
- modifying gravity (e.g. Moons gravity is 1.62 m/s^2),
- and limiting the balls movement only to the z axis.
Download the template project with table tennis assets.
Sound assets used:
- Ping pong ball hitting table: https://freesound.org/people/mazbord/sounds/622626/
- Ping pong ball hitting racket: https://freesound.org/people/Emmalyons1/sounds/594190/
Lab 5 (12.03) - Locomotion (Task 5)
Implementing smooth locomotion to extend the default UE VR pawn using the default VR template.
- Create a new Pawn by copying the existing VRPawn and change its parent class to Character.
- Add new input for thumbstick axis and potentially remap the turning inputs.
- Doing this via the enhanced input system results in most flexibility.
- Use the new inputs to add character movement input.
- Keep the character actors horizontal location at the same world location as the camera components world location.
This lab is based on a new VR Template project where we will get familiar with the existing locomotion and then modify it by extending the default UE VRPawn. We will use the UE Enhanced Input System for most flexibility - https://dev.epicgames.com/community/learning/tutorials/eD13/unreal-engine-enhanced-input-in-ue5 . See the final blueprints provided after the lab session in Discord.
Location of the locomotion input components in the Content Browser:
- /All/Game/VRTemplate/Input/ - Input Mapping Context (IMC) assets
- /All/Game/VRTemplate/Input/Actions - Input Action (IA) assets
Open the IA_Turn and familiarize yourself with the parameters-values under the Action and Modifiers sections.
Open the IMC_Default and do the same under the Mappings for IA_Move and IA_Turn controls for Oculus.
Change the left thumbstick mapping for turning action to be the right thumbstick instead:
- IMC_Default > Mappings > IA_Turn > Oculus Touch (L) Thumbstick X-Axis
Test your modification in VR.
Add a new input action for the joystick and name it IA_MoveJoystick: Where you have the IA_Move asset, you now additionally have IA_MoveJoystick asset. In your freshly added IA, change the Value Type to Axis2D (Vector2D) under the Action section and add one new modifier with a value Dead Zone under the Modifiers section. Notice the threshold values of the freshly added modifier but leave them as is.
Change the default IMC input action mapping for Move to your new IA_MoveJoystick:
- IMC_Default > Mappings > IA_MoveJoystick
Change the right thumbstick mapping to be the right 2D axis thumbstick:
- IMC_Default > Mappings > Oculus Touch (R) 2D-Axis
You can also remove the other unused control options.
Locate the VRTemplate Blueprints directory and the VRPawn blueprint (BP). Create a copy of the VRPawn, rename the original to VRPawn_original and rename the copy to VRCharacter.
Open the VRCharacter BP and locate the Input Action Move - Teleport group in the Event Graph. Select this group of nodes together with the surrounding comment and remove it.
Add a new EnhancedInputAction event for when your newly created IA_MoveJoystick triggers. Add a new Print String node, connect it to the event node and connect the event's Action Value output to the Print String function's In String input. The second connection will automatically add a conversion node, take a closer look what gets converted. In general, the Print String function can be useful for debugging and prints your configured value out in Play Mode.
Test in VR.
In the VRCharacter BP, go to the Viewport tab and notice the types of different objects under the Components section on the left. Locate the root component of this BP (it is not the VRCharacter!) and notice its details on the right. Navigate to the Class Settings tab and notice the parent class of the VRCharacter - it is currently Pawn.
Change the parent class of the VRCharacter from Pawn to Character. You can do it on the right side, under the Class Options section, after you have selected the VRCharacter component and navigated to the Class Settings. Notice the description of the Character class - it says that a character is a type of Pawn that includes the ability to walk around. This is exactly what we need, allowing us to add physics based movement to our character.
Notice the resulting change also in the objects in the Components section under the VRCharacter. Now the root component of the VRCharacter is a Capsule Component, which also has collision. And now there exists also a Character Movement component, which is important for the movement logic. It might be useful here to read the description of the Character Movement component.
Locate the Player Start on the map and notice that the capsule is partly inside the floor with a Bad Size warning. On the map, move the capsule upwards, just so it is above the floor. The warning should disappear as well.
Test in VR.
- Test it also with unpossessed character (Alt + S in Play Mode) so you can see the character in the Play Mode without being in the first person view of the character.
On the map, select the Player Start and on the right, in the Details, under the Actor section, change the Spawn Collision Handling Method to Always Spawn, Ignore Collisions.
In the VRCharacter BP, select the Capsule Component on the left and notice the Shape parameters-values on the right. To modify the height of our character viewpoint, instead of manually moving it, add a Scene component to the Capsule Component and name it to VROffsetRoot. Move the VROrigin component to be the child of the VROffsetRoot (simply drag it on the new targeted parent component).
Go to the Construction Script tab in the VRCharacter BP. Add VROffsetRoot component node to the construction script node graph (drag the component from the left or right click directly on the node graph empty area and use the Get function of the component). Add a node to the VROffsetRoot output to set its relative location. Add also the Capsule Component to the construction script node graph and to its output add the half height variable from its shape (start searching 'half height' and select the Get Capsule Half Height function from under the Variables/Shape). Multiply the Capsule Half Height output with -1 using a multiplication operator node and connect the result to the Set Relative Location Z input (use Split Struct Pin on a node whenever you need to ungroup the XYZ). Compile.
Adjust the half height and radius values to your liking.
Test in VR.
To make our character move, locate the IA_MoveJoystick event node on the VRCharacter BP (where we currently have the Print String function as a temporary debug aid that you can now disconnect), leave a bit space on the right (there will be several intermediate nodes there) and then add an Add Movement Input node. At first, recheck the Action Value type of the IA_MoveJoystick output (mouseover is enough). Notice that this is not compatible with the Add Movement Input node target input. We need to do conversions next, before connecting anything to the Add Movement Input node.
Add a Draw Debug Arrow node to the joystick trigger event. But do not connect the arrow output to the Add Movement Input node just yet. Change the arrow size, line color and thickness to something more visible, e.g. 5.0, blue and 1.0 accordingly. Duration is ok to leave 0.0.
Our goal is to show our character's moving direction using a debug arrow. The arrow pointing direction will be the left controller's aim direction.
For the arrow Line Start, use the Motion Controller Left Aim component (drag or use the Get function), but notice that you need to do a transform to the world location before connecting it to the Line Start input. For this transform, first add and connect a Get World Location node between the controller's node output and the arrow's node Line Start input. Then also add a Get World Transform node to the controller's node output. From the world transform output add a Transform Direction node. After you have added the direction transform node, notice that now when you connect the joystick event's Action Value to the Transform Direction (Direction vector), it becomes possible and a conversion node between the vectors is added automatically. To finish the arrow line end, add a Project Vector on to Plane node to the Transform Direction output, change the Z value from 0.0 to 1.0 and multiply the projection node output by 30.0 (note that you can convert the multiplier operator to a Float before). Add an addition operator before the debug arrow Line End input and add together the multiplied vector projection output and the world location output.
Test in VR.
The arrow should be pointing almost to the correct direction.
In the IA_MoveJoystick asset window, under the modifiers, add a new modifier and change the value from None to Swizzle Input Axis Values. The default order is ok.
Test in VR.
The arrow should be pointing to the correct location now when you move your aim.
Now you can connect the debug arrow output to the Add Movement Input node and also connect the projection node's output to the Add Movement Input node's World Direction input.
For the character turning which we did not have time in the class, see the provided blueprint (Discord) and try to do it yourself.
Summary of the transformations done:
- Input - from basic default mappings to UE Enhanced Input System that allows more flexibility.
- Blueprint - from simple Pawn class to Character class with physics based movement.
- Movement - from raw joystick values to world space directional vectors that are suitable for VR locomotion.
- Cam height - virtual cam position aligned to player height dynamically.
If you want to get more familiar to blueprint scripting in Unreal Engine, here is a general Quickstart Guide (~2 min read): https://dev.epicgames.com/documentation/en-us/unreal-engine/quick-start-guide-for-blueprints-visual-scripting-in-unreal-engine
Lab 6 (19.03) - Interactions (Task 4)
Make a basic auto-latching door in UE as described in the lecture slides video.
- Optional: Additionally you could try to add an interactive lock to the door that can be toggled/unlocked with a keycard.
Download the template project with door assets.
Lab 7 (26.03) - Project team forming
Lab 8 (02.04) - Prototyping
Lab 9 (09.04) - Graphics. Git setup. (Task: M1 prep)
Lab 10 (16.04) - Visuals in VR (Task 7). Project M1 presentations.
- Download the button and the lever base models from here.
- Fix the problems
- Separate the button into two moving parts
- Fix the normals on the button
- Fix the shading on the parts of the lever
- Fix the origin of the lever handle to make it move nicely
- Import them to Unreal
- Create LODs for them
Lab 11 (23.04) - Lighting in VR (Task 8)
- Create a custom lighting scenario in the provided project
Lab 12 (30.04) - Animations. Work on the project. (Task: M2 prep)
Lab 13 (07.05) - Audio (Task 9). Project M2 presentations.
Lab 14 (14.05) - Deploy to Quest (Task 10)
- The goal is to build and run an UE project on Quest.
- For this check out this guide document