Realistic Advanced VR Project Implementation 2
Cognitive dissonance that can occur
when moving using typical movement methods in VR
In other words, we will take some time to experience the sensation of dizziness
To prevent this cognitive dissonance
we will directly implement the teleportation movement method
which is commonly used in VR apps
At this time
to continuously display the location to teleport in real-time
we will use a method that predicts the trajectory of a projectile
when an object is thrown
Drawing the movement prediction line
We will use the right thumbstick for movement
So first, go to the Inputs folder
right-click
and add an Input Action in the Inputs folder
Name it IA_ThumbstickAxis_Right
to create an Input Action
that retrieves the thumbstick axis values for the right hand
Of course, since it's an axis value, there will be X and Y
So I'll receive it as Axis 2D
and then I'll add this value
as a mapping in the Input Mapping Context
Click on the plus sign to add one
and here I'll add IA_ThumbstickAxis_Right
The Oculus Touch controller has
a Thumbstick 2D-Axis on the right side
So I'll retrieve the 2D-Axis
Shall we also implement the default movement method while we're at it?
Let's open the HunetVRPlayer Pawn
Last time we were working on the Player Pawn, right?
Let's add
the IA_ThumbstickAxis_Right event here
If we're using
the typical movement method we've been using
then whenever Triggered
we'll use Set Actor Location to specify a position
and move the actor there
However, in this typical movement method
we'll take the direction
we're pointing the thumbstick
and get the Action Value as a Vector
Let's split this Vector structure
When we split it, we'll get separate X and Y values
So, the Y value from the thumbstick represents the up and down movements
X from the thumbstick represents left and right movements
So, the up and down value should go into the Z axis
and the left and right value (X) should go into the Y axis
Split the New Location as well
The X value will go into the Y axis, representing left and right
Then, the Y value from the thumbstick
which indicates forward and backward movement for the player
will go into the X axis
However, we can't just put it in directly
If we put it in directly, it would start from the origin
So, first, get the Actor Location value
use Make Vector to create a new vector
where X goes into Y and Y goes into X
then add these two values together
Normalize this value first
then convert it to Float by multiplying it
to set the movement speed to around 600
Then recombine this value here
pass it as a Vector like this, compile, save
This is basically using
the typical character movement method
we've been using so far
Except instead of using the W, S, A, D keys on the keyboard
we've translated that into the X and Y axis values
from the thumbstick
If we do it this way, the movement itself should work fine
You raise your right hand
and move it forward and backward
with the object floating in the air
set to Z value of 0
If you set the Z value to the current position value
anyway, currently moving forward will result in movement
The current Z value seems to be causing some issues
So, I'll normalize it to adjust the position
I'll normalize the vector
then multiply this normalized value
by the speed
and add it here to pass the combined value
That way it will be P = P₀ + Vt
Compile, save
and then the speed is incredibly fast at 600
so I can confirm it moves forward and backward well
Maybe the speed value here is too high right now
So, even giving it around 100 should be sufficient
but even at 50
it seems quite fast
It moves well with left hand
and right hand controls like this
However, once you start using it
you might find it quite dizzying
Because the speed perceived by our ears
and the speed perceived by our eyes need to match
Because our ears don't sense speed
but if our visual information keeps suggesting movement
while we're actually still
it can confuse the brain
To prevent that confusion
teleporting to a specified location instantly
is considered
a more common method in VR
So, I'll separate this part into a separate function
Since you might use it later
I'll name this section 'Normal Move'
I'll create a function named 'NormalMove'
First, we need to receive input values
so let's add an input parameter here
So, let's call it Input Value
And the type we're receiving should be Vector 2D. It should be in vector form
Vector 2D instead of 3D
We have the Vector 2D Structure
for this change
So, let's receive Input Value as a Vector 2D
Next, in the Event Graph
let's cut these nodes with Ctrl + X
paste them into the Normal Move function
with Ctrl + V
and then split them
so that X goes into Y and Y goes into X as we discussed
I'll move these nodes a bit lower, down here
and connect the execution pin to Set Actor like this
So, if you want to use this
you would place it like this
and recombine the input
when Triggered to pass it like this
implementing it this way
So, you want it to stop when Completed as well
If you place Action Value like this
when Completed
it should streamline the functionality
while still working well
But as I mentioned earlier, this can be quite disorienting
So, let's not use the Normal Move method
Instead, let's delete it by pressing the Delete key
We'll use the Teleport method instead
In the Teleport method
Unreal Engine provides a way
to predict projectile curves
So, using this
you would search for 'Predict Projectile Path' in the node search
There are various options like ObjectType, TraceChannel
and Advanced methods available
Let's try the TraceChannel method first
Using the TraceChannel method
in Predict Projectile
when drawing the curve
it should stop if it hits something
So, the Advanced method
allows you to specify both
ObjectType allows collision detection
only with specified object types
TraceChannel specifically performs collision checks
using visibility and camera channels
in the TraceChannel method
get it?
We'll go with the TraceChannel Visibility Channel search method
for a more concise implementation
Then first, we need to make sure
the line is drawn correctly
I will start drawing
from the position of the right hand
When you use the Right Montion Controller
to Get Location, you’ll see Get World Location
So, you’ll do Get World Location
and this position will be the starting point
So, if you were to throw a virtual projectile
it’s about drawing how it would fly
while drawing a curve
Velocity, when I said how much force
and in which direction will you throw
I'm going to throw in the front direction of the Motion Controller
and the Forward Vector direction
But at this point, since the Forward Vector has a magnitude of 1
the power will be too weak
So, to make the power stronger
I’ll add a variable here
So, I’ll call it Teleport power
I’ll make this power a Float variable
so that as the power increases, the teleportation distance also increases
The data type will be Float
Let’s compoile first to get the default values
and then I’ll set the power
to around 650 once we see them
So, we’ll multiply the Teleport Power
by the Forward Vector
after getting the Teleport Power and Forward Vector
We’ll multiply these to get the product
which will then be passed as the velocity value
Next, we’ll determine the thickness of the projectile
So, we’ll set the size of the projectile
to about 30 units
Since the capsule is approximately 30 cm in radius
we’ll match the size
to that of the capsule
And the channel we’re looking for is
the Visibility Channel
it’ll prevent
further teleportation
acting as a blocker
Next, when checking for collisions
I shouldn’t collide with myself
as the player
So, let’s create an array using Make Array
and I’ll pass this array here
So, using Self as the Actor
we’ll set Reference Self as the Ignore Actor
to ensure collision processing ignores oneself
We’ll continue displaying this projectile
when we press the button
So, let’s first debug to make sure
the line is drawn correctly
So, we’ll draw it for just one frame to check
if it’s working correctly
Since it’ll be continuously drawn while the button is held down
we’ll keep it drawing repeatedly
Next, there’s the frequence parameter
This determines
how long the simulation will draw for
Let’s set it to around 15 seconds for the simulation duration
The rest doesn’t seem to need any adjustments for now
Let’s first cheeck if everything works correctly in this state
Compile, save
and test the predictive line during gameplay
If you move the thumbstick, how does it appear?
Right now, you can see the large capsules
drawing lines as they move
The capsules are too thick, considering they’re 30 cm
So, when you press the button, it draws
and when you release it
if you tilt the thumbstick in any direction
it draws lines in that direction, following where your hand points
So, you’ve confirmed that the lines are drawing correctly now
It seems like the lines were quite thick
But we don’t intend to draw those debug lines
we actualy want the user to see them
as visible lines
So, let’s change Debug to None for now
and we won’t draw those debug lines anymore
Let’s reduce the Projectile Radius
to around 15 or even 10, since it seemed too large earlier
So, you saw those circles drawn earlier
in green like that
When the circles are drawn
their coordinates will be returned
as an array called Path Positions
So, we’ll use this array of vectors
to draw the picture along this line
Displaying Niagara Effect
I’m going to use Niagara Effect
to make it look more visually appealing this time
If you use “Player - Add”
you’ll find a component
called Niagara Particle System Component
Add a Niagara Particle System Component
Let’s name it Teleport Line
If you go to the right in this Teleport Line
you’ll see the Niagara System Asset
Here, if you click on it
you’ll find the default line that was included in the VR template
Let’s reuse that
by assigning it to our Teleport Line
So, we’l use the effect file named
TeleportTrace
If you click the folder icon below
the original location will appear
It’s in the folder called VFX in the VR template
Shall we take a look at what the effect looks like?
I’ll double-click it to open and take a look
Then, if you look here, it’s this kind of line
There’s like a slight rainbow colored line
But if you take a look here
the length of this line is determined by
if you go to the tab called User Parameters
there’s a variable called Point Array
and there are some values
So if you change this value to a different one
the 0th position will be the starting point
The 1st point will be around here, the 2nd point around here, and the 3rd point will
bend like this
If you change, for example
the 4th point to a different value, what happens?
The line would twist or become tangled in this manner
It seems to come from over there like this
From this side, it goes like this
It looks like the last number is at the very first position
So if you increase this to 150
it’ll move to a higher position like this
So, in the end, what we need to do is
to pass the actual vector coordinates
that we want to draw into this array
called Point Array
in the User Parameters of the Niagara Effect
So, first, I’ll delete all of them
and then I’ll leave just two I’ll set them to 0, 0
Then they won’t be drawn on the screen
But if you draw something like this here
it’ll appear on the screen like this
in this manner
We’ll set it to 0, 0, 0 initially
so nothing is drawn at first
Then, we’ll make the line appear only when we move the thumbstick
First, compile and save
Right now, it’s trying to draw the Teleport Effect
but since all the values are 0, 0
it’s showing an exclamation mark
However, it’s not a major issue
I’ll save it in this state for now
It’s probably due to the TeleportColor animation
It’s because of this
but you don’t need to worry too much about it
First, go to HunterPlayer
and we attached the Teleport Trace effect
to the Teleport Line earlier
So, we just need to pass this array
to the User Parameters here
So, from the Teleport Line
we’ll use the Niagara Set Vector Array
Select the Niagara Set Vector Array
When the projectile array is drawn
we’ll pass its value to this Niagara component
But earlier, we need to use the name of the User Parameters
which is Point Array
Just to be sure
I’ll copy the name exactly as it appears here
Right-click here
choose Rename, and by pressing Ctrl+C
I will copy the name
And then Ctrl+V
to paste like this
Compile and save
Debug mode is turned off, set to None
And then
we passed the calculated position values
to Niagara as an array
Let’s take a look at how it looks now
I’ll press PLAY
and move the right thumbstick to see how it works
Then you should see the line being drawn
as you move the thumbstick in this direction
You can see that line continues to be drawn like this
Since we don’t instruct it to erase the line when the button is released
you’ll see the line remaining in its current state
Next, if you draw like this
and then move thumbstick
you’ll see the line remaining in its current state
First, if you feel the line is too thin
select the TeleportColor here
There should be an option called Bean Width here
Beam Width controls the width of the beam
We’re currently using the Beam Effect
and if you’re looking at the Beam Width
in the Details Panel
it ranges from
0 to 3.5 for thickness
It seems to have a design where the middle is slightly thicker
and it tapers thinner towards the ends
So instead of just leaving it like this
set the value here to 3
The height should be 3
Set the slope back to 0 and also set this to 3
If you flatten the slope like this
it’ll just be straight and even, so it should be 3,3
If you connect it all straight to 3cm
the line will probably appear thicker
Compile and save
Now the line has definitely become thicker compared to before
and it’s consistent in thickness because it’s set to 3
You can see that it’s drawing consistenly
with the same thickness throughout
not just thicker in the middle but uniformly 3cm thick
But as the line extends further
without some indication of where I’m moving towards
it can be difficult to grasp my actual orientation
just from the line
So, add another Niagara Particle Ssytem Component here
for the Niagara Effect
This is for the teleport destination
so let’s name it “Destination”
Add another Niagara Component
named “Teleport Destination”
I’ll add the effect called “Teleport Ring”
to the Niagara Component
If you click on the folder
you’ll find that the Teleport Ring effect looks something like this
it creates a circular effect
that could indicate an arrival point
So, we’ll display this effect
We’ll check “Set World Location”
for the Teleport Destination position
For the position
it should be the last point in this Array Data
which will be the destination point
Here, you can see
there’s a Last Destination under Trace
We’ll pass this position to New Location here for the Last Destination
Take a moment to organize the line
By setting up like this and compiling and saving
the “Teleport Destination” should now
follow along at the end of this line
Let’s test it out
Then you should see a circle marker
always appearing at the end point now
But when you release, this marker should disappear
So let’s add the functionality for it to disappear
when released
Implementing of the Teleport feature
Since the line is quite complex
let’s push back this part slightly
and we need to know the position when it’s released
So, currently, we’re only capturing this position
when it’s triggered
meaning when it’s completed, we can’t know this value
We can’t retrieve this value
So, let’s store this value in a variable
Should we create a variable for this?
Let’s add a variable
and name it “Destination Location”
We’ll change the data type to Vector
for the destination location variable
Compile and save
So, we’ll continue to set the Destination Location
to be the same as
the position of the Teleport and Teleport Ring
Let’s assign this value here as well
We’ll connect it like this to make sure it’s linked properly
So, the last position will be
set to the position of the Teleport Ring
and we’ll also save that position in a variable
So, when it’s completed
we should actually do what? We need to erase the line
Therefore, if you search for
“Set Vector Array” in Teleport Line
you’ll find the Niagara Set Vector Array node
To be safe, let’s copy the name of the point from earlier
To avoid typos
let’s copy and paste “Point Array”
as the name for the User parameters here
Next, we should clear out the Array Data
So, use “Make Array”
to pass this empty array
So, we’ll do this when it’s completed first
Then we should hide
the Teleport Ring and Destination Ring as well
So, connect the execution pin to Set Visibility for this
Set Visibility will be set to False
Then, since the Visibility is off, it's not visible
Then, I'll move the Actor later
And stop at this point first
I'm going to off Set Visibility
If you turn off the Set Visibility here
When you click it again
Since Visibility is off
Even though you change
the Set Position to
Teleport Destination
The Destination position will not be seen
Because Visibility is off
So, before changing Location
When you draw the line that turns on Set Visibility
You have to turn on Teleport Ring again, too
So, I will check Visibility
to True state
So that I can make this to move there
Compile, and save
I'm going to test
whether the line is well drawn and erased
Press Play button
When you move the Thumbstick
and when it's on moving state
it is shown on the screen
When you take off your hand from Thumbstick
The line gets erased
So, we can check out
that it is well shown like this
So we can now specify the destination
and movement location like this
Then, finally, you have to move
When should we move?
When we are drawing line and aiming
we should not move
I'm going to aim so I have a clear idea of ​​where I want to go
and then have it move when I release my hand
from the Thumbstick
So, when we move, we can set my location
Set Actor Location
Where?
The place where we set Destination
You can move here
What happens when you just move?
We will get buried under the ground
Actually, when Destination is on the ground
We aim the ground's end point
and ground's hit point
and saved as destination
We should be slightly higher than that
So, as much as the capsule's height
Let's raise about 50
By +Add, we will raise
about 50cm to Z axis
So, we will convey the value to New Location
Compile, save
Teleport, move PLAY
Then, aim here like this
move in front of the desk and when you look back
you can see the table at the back
To move to the side of the table
After aiming like this and move
table is now on the right
like this
We implemented the movement function
Since it's complicated, I'll organize the nodes
So add a function here
And make a functin
named Draw Teleport Line
And at Draw Teleport Line function
You know the nodes that were
connected at Triggered function at Event Graph
I will cut all of them by Ctrl+X
and paste it at
Draw Teleport Line
Then, I'll connect the execution pin here like this
Then go to Event Graph
bring Draw Teleport Line function
and connect to Triggered
It's more clean, right?
Add one more function
and name it Teleport Action this time
Make Teleport Action function
and cut all the nodes that were stuck at
Completed in Event Graph
and paste it at Teleport Action
Then, here, connect the execution pin
At Event Graph
bring Teleport Action function
and connect at Completed
Then the functions will be more clear
You always have to test if there's any problem
when it's made with function
Teleport movement PLAY organized by function
It is well drawn, and if we let it go, it moves
So we can find out that
it is moved well like this
So, when we are going to move
whether we are going to do Teleport movement
or Normal movement
we have to think about under the circumstance
If natural movement
Even if it requires overcoming a little dizziness
when the content needs natural movement
You can use the basic movement
normal movement
Otherwise, I want to look around
and move without dizziness is more important
Movement is not main
Like this, using Teleport Line
to move to Teleport
Configuring the contents like that will be much better
So, there's no right answer
Depending on the situation
you can decide which one is better by actually experiencing and implementing
moving it according to the content
and adopt the movement method
that you think is more suitable or comfortable
I will wrap up the content we learned in this lecture
First, by implementing and experiencing
both normal and teleport movement methods
we looked into ways to minimize the cognitive dissonance phenomenon
caused by the discrepancy between visual information and balance organ information
Second, the Predict Projectile Path function node
used when drawing the Teleport Line is
a node often used when simulating the movement
process of an object
to predict the actual physical movement path
it even calculates the case of collision with other objects on the path
Please be aware of that
Lastly, when applying an effect using the Niagara Effect
there may be cases where the settings
need to be adjusted in real time to suit the current situation
Please remember that
you can easily change data
using User Parameters in the Niagara system
Draw a moving prediction line Add Input Action and Bind Button
Start by creating a new Input Action by selecting +Add - Input - Input Action in the Inputs folder of the Content Drawer
Double-click the IMC_HunetInputMappings file to open the settings window and assign the IA_ThumbstickAxis_Right file to the Mappings array
The button to connect is the Thumbstick 2D-Axis button on the VR controller (R)
Basic movement implementation: Verify that when you tilt the right thumbstick while playing, the character moves forward, bakcward, left, and right
It has been observed that wearing VR equipment and performing basic movements frequently can cause dizziness (cognitive dissonance phenomenon)
Drawing the projectile prediction line Delete all existing Noraml Move nodes
Create the node Predict Projectile Path by TraceChannel for calculating the projectile’s trajectory, then connect it to the Triggered event execution pin
Set the start position (Start Pos) of the prediction to the position of the Right Motion Controller
and set the launch velocity to the forward direction of the motion controller multiplied by 650
Set the channel to be detected to the Visibility Channel and exclude the actor itself (Self) from the detection target
For verification purposes, set the Draw Debug Type to For One Frame
Verify that when you move the right thumbstick while playing, a sphere is drawn along the predicted trajectory line
Displaying Niagara Effect: Draw Projectile Prediction Line Start by selecting +Add - Niagara particle system component in the components panel of
BP_HunetVRPlayer settings window to add the Niagara Component
Verify that when playing and manipulating the right thumbstick, lines are drawn using the Niagara Effect
Lines are drawn accurately, but the arrival point isn’t clearly indicated, suggesting the need for an additional effect
Displaying ring effect at the target point: Begin by adding a Niagara Particle System Component to be used at the movement destination point
Verify that the ring effect appears at the end of the line during play Verify the issue where effect doesn’t disappear when releasing the button
Turn off the teleport line and ring effect: Implement the logic so that when releasing the right thumbstick, the line and effect disappear
After connecting the nodes, verify that tilting the right thumbstick draws the line, and releasing the thumbstick erases the line
Implementing teleport functionality: Move to the destination when teleporting Use the Destination Location variable
saved when drawing the teleport line as the New Location input for Set Actor Location on the new actor
To prevent the player pawn from moving to the ground where the teleport ring is drawn
Set the teleport destination by adding 50 units to the Z-axis of the Destination Location variable to ensure the position is above ground level
After playing again, move the right thumbstick to select the teleport destination, and when releasing the thumbstick, verify that the player moves to that location accordingly
Organize the Blueprint nodes: Connect the Triggered execution pin of the IA_ThumbstickAxis_Right node to the Draw Teleport Line function node
and connect the Completed execution pin to the Teleport Action function node