Hey and welcome back to the third person camera tutorials
and unity in this lesson. We're going to be
extending our camera from this targeting behavior that we have
here. We're going to add one more behavior.
It's a first person mode. So in Wind Waker,
you're able to press up on the C stick
or I guess really the right thumb stick and look
around the world and just kind of observe your surroundings
and ascertain. I guess what you need to do
in the game. So we're gonna go ahead and
implement that in our game. But first, if
you're wondering, it looks a little different. Um
I just added a bloom script and a uh ambient
occlusion script because that's what all the all the cool
games do these days. So what we're gonna do
is we're gonna go back into our camera script,
we're gonna start adding stuff to it. And the
first thing we're going to add is a, it's
not any logic but it's just struct which is just
really a collection of values that we're going to store
our camera position in for when we actually want to
do this, this first person behavior. So we'll
save that, we'll have a look at this.
So we've got a position where we're actually going to
align the camera too transform, which is going to
be where we're going to place the game object and
we're gonna have an initialized or function or we're going
to parent it. So the basic idea is we're
going to have our character here in the hierarchy.
We're going to take um the characters based hierarchy and
we're just going to place an object right around here,
like right in front of right in front of
the character's face. And then that way we'll have
something to rely on our camera to when we go
into this mode. So next thing is we need
to go ahead and create that that variable. And
what we're gonna do is we're gonna call it the
a first person transform. And we're going to initialize
it in the start method. So in the start
method we're going to add a new initializer. We're
going to say first person camera position equals new camera
position. We're gonna declare a new one of these
objects And we're gonna store within it. Uh we're
gonna put it at this position which is 1.6 m
up from the base of the character. And we're
going to create a new object in your game object
Uh We're going to assign, it's transformed to.
that transformed variable here. So we have a way
to manipulate it and we're going to say that the
parent is just the parent of of our characters.
So we're just gonna parented to the characters main transform.
So that's pretty simple and we need to put
this variable up at the top of our scripts so
just take the variable and add it to our private
variable section save. And let's make sure that compiles
. Okay, so we've got an error so we
don't actually have a reference to our follow yet.
The best way to do that is we're just going
to pass in follow X form here, which is
the name of our transform. Yeah, it seemed
to do it and let's make sure that that works
Perfect. So you can see right here, we
just created that camera, we gave it a name
, first person camera, which is just what was
declared as here. And it's 1.6 m up from
the character. And it's great because as we move
around it sits in front of the character's face.
So that's we're gonna try to position our camera.
So next let's create a new camera state and we're
going to have some logic for moving into this uh
first person camera mode. And since we want to
use the right stick to know when to go into
this mode, we're gonna need to pull in values
for the right stick. So in our update method
are lit update method. We need to pull in
values for right X. And write Y. But
we also need left X and left Y. Because
we're going to be using the right stick to move
into that mode, we're going to be using the.
left stick to control the camera while we're in it
Okay, perfect. So let's save this and
you'll notice if we play the game now, it's
going to say that we don't have actually doesn't give
us a warning, but it's because I've already changed
it. If you just go to the input manager,
we need to actually create new inputs for this
right action. Right? Why variable? So if
you have a look at the Xbox controller setup which
is right here and noticed that the stick is accesses
five and four. So I've just placed five and
4 in here and set the gravity, the dead
zone and the sensitivity to 1.1 and one. That's
all there is to do for that. And now
we've got our values for these axes. Let's have
the logic in now to determine when we actually want
to enter this state. So we'll say if the
we'll go ahead and paste this in here. So
the right wife this stick goes higher than some threshold
and the state is not we don't have this camera
state yet so we'll delete this. If the character
is not moving and we pushed the right Y stick
up then we want to enter this free person are
free. Sorry first person camera state. So we
need this first person threshold variable. And we're going
to set that something that the user can set a
serialized variable in the Inspector. It's a place out
there. We're missing a couple more variables that are
used in this. We don't have an X.
Axis rotation yet. And what that's going to be
is as the character is looking we need to store
some variable for this up and down. I know
it looks like he's looking up and down. But
if you think about it and unity the axes are
uh like you look at the X. Is the
X. Axis is the one that is being turned
on. So we'd be actually turning sort of like
if you think of this controller is turning on its
X axis, X axis is looking up and down
. So I want to store the amount of expectation
that we've achieved so far to restore that in a
variable. And we also want to make the character's
head look up and down. So as he's as
he's looking we won't actually move the character's head using
some variables in mechanism. So what's that? There's
two variable suit. Mhm. And save and hopefully
you won't get any years. Okay. So we
need one more thing so we need to actually a
reference now to the controller script which is a little
bad because it makes our scripts a little more tightly
coupled. But in this case it's okay because we
don't ever want to have a third person camera without
a character controller logic. So we're going to add
a new variable up here at the top and we're
gonna make it serialized, you're going to make a
private character controller logic, This color follow. And
it's pretty easy to get this. All we have
to do is just use this tag again. So
let's grab the tag and that should do it.
We just follow transform. We describe the players transform
for follow the regular object. We describe the character
controller logic component. So hopefully that'll that'll do us
. Okay, great. We want to add one
more thing in this sort of decision section of our
script. We're trying to decide what camera state we
want to go into and that is we need to
add a state. Now we need to add logic
for when you want to go into the behind the
back mode because now we have two modes that aren't
the targeting mode and the logic for this one is
pretty simple as well if the camera state isn't first
person and we haven't exited first person yet, so
we need to add this into our into our input
as well. This exit button is basically just a
button to exit out of the mood. You can
target to get out of the first person mode,
but you also want to be able to hit B
to get out of the first person mode. So
here we can hit B and exit this mode.
Want to add a button for that too. So
we're gonna call exit first person view and we're just
going to set it to the joystick button one which
here is the B button on the on the Xbox
controller and you can go ahead and leave all the
sensitivity and gravity the same. So if we're in
first person and we've exited, first person were in
targeting and the targeting button is less than the threshold
. We want to move into the camera state that's
behind camera state. So let's say that if we
don't get here's he's a targeting threshold, we need
to create a variable for that that we're going to
set. Probably too uh Point at one is a
good value. Mhm. And we just want to
copy that into our variables up at the top,
so it's just a constant. Okay, it looks
like it looks like it compiled. This is a
test. Let's make sure that we're getting into the
right mood. We can just set a so we've
got this camera state first person, let's just create
a new case in our switch statement for that particular
state. Mhm. And let's just add a debug
statement just so we know that we actually managed to
get into this state properly. Okay to me.
Okay mm. So we'll see how that works.
Go ahead and hit play. So if we press
up on the steak we've entered the first person and
you can see that in the log down here.
If we trigger, we're not in the first person
mode anymore, you can see that we're not getting
this anymore, we can have a look there.
And also if we enter the first person mode by
pressing the stick up and then pressing B we've now
exited the first person mode and it's not running that
debug statement anymore. It looks like our logic is
pretty sound for that. Now that we know that
the mode is working properly. The thing we want
to do next is to actually make the character look
up and down. So to do that we're going
to need to grab a variable from the character which
is the look at. We need to create a
new variable called look at weight. And that's going
to be how the character is looking. Um Using
mechanism was beckoning. You can have access to the
characters neck and manipulate the head and move it up
and down. So it's had a new local variable
. Call it look wait. And we're going to
want to we're going to want to set that two
20 a friend. The first person mode. We've
already actually created it so I don't need to create
it again. But we want to we want to
set it equal when I actually set this on update
. So we're gonna grab the follow objects which is
our character controller. Want to grab its animator one
actually set the characters look wait to this to this
value. The thing is we need to actually have
the animator be a public property which we haven't done
yet. Yeah so we'll copy that in here.
So that's good. Now let's make sure that that
compose nice. We need to actually set a value
for that. Look wait now we're going to be
doing that in the first person. So the first
thing we want to do is have logic for looking
up and down and then later we'll go back and
add logic in for actually moving the character on its
on its Y axis. So we work on the
X. Axis first. Okay it's a lot of
good. I'm about to copy in but I'll be
sure to explain it. So it's the logic for
looking up and down. Basically we want to do
is you want to calculate the amount that we want
to rotate on the X. Axis by taking the
left stick. Multiplying it by I just multiplied about
half because it feels a little better if it's a
little smaller value you want to multiply that by the
first person look speed which is a new variable.
We need to add yeah to our scripts and that's
just gonna be how fast you want the character to
actually look. So if we go back to unity
and compile it looks like we're missing this variable as
well. And this is a clamp value that we
need to set so that we can't look more than
a certain degrees up and down. You don't want
to look too far to your feet. You don't
want to look too far backwards or else you snap
the characters neck which is definitely not a good thing
. So let's grab this variable and we'll add a
clamp value. We want to make this serialize that
people can change it and that should be good.
Let's move this up into the serialized section two.
Yeah. Okay great. So now we've got The
x axis rotation. We're calculating it actually it's probably
smarter just not to use this half value. I
don't know why. That's not great to put constants
in there. We can just make this a little
bit smaller value. So at 1.5. So make
that uh we'll make the X. Axis rotation,
the left wide stick plus some speed. We're going
to clamp that value between X and Y. For
our client values. And this isn't really X.
And Y. Is just a convenient way of giving
it to values. It's not representative of direction.
And then the next thing I want to do is
want to set the first person camps position that transform
, want to set its rotation equal to that,
to that new rotation value. It's actually common out
these lines for a second just so you can see
the effect of that. Okay so let's enter the
first person mode. You can't actually see it yet
. But I think we're in it and if we
press on the Y stick uh gonna be a little
tricky to do, hold on once again want to
set this following, moved back on. It will
be useful for what we're doing here. So let's
have a look at the first person camera move into
first person mood and you can see as we move
up and down on the stick that transform moves.
So it's exactly we wanted we just want to point
this transform up and down. It doesn't work how
we want it yet just because we haven't actually put
the logic in to translate this onto the character's face
. So how can we move that rotation from that
game object onto the actual rotation of the camera?
I think if you remember from the character controller we
use this method called from two rotation for Quattrone ins
and then we made that give us a referential shift
, just some sort of reference from one rotation to
another, how far it's changed. And then we
were able to use the quaternary multiplication to sort of
can candidate these two rotations together? What exactly we're
going to do here? We're going to take this
, we're going to create a shift by using the
ford transforming the camera and the forward transform of this
rotational game object that we have here. I just
want to translate this thing's rotation and we want to
sort of reference how much that's rotated and store that
onto our cameras rotation. So we get the same
shift and then she's quadrennium multiplication to put that under
the camera. So let's give that a shot now
it should move the camera as well. So enter
the first person, nobody is tapping up on the
steak and see where is our character. There you
go. So the reason it's not moving it yet
is because we have this look at function that's already
positioning the camera and and sort of overriding this rotation
that we're sitting here. So I'm gonna have to
add some logic to store a new variable and we're
gonna have to look at something else. So this
is a little tricky here. It was kinda hard
to figure out how to do this. But we
basically just need to create a new vector three to
look at. So we'll call this vector three,
we're just gonna call it look at just a nice
simple name. Let's default that value to just be
the characters offset. That's normally what we're looking at
for both of these two cases, we're looking at
the character offset so let's go ahead and just defaulted
there and then we're going to only change it if
we need to, What do we want to change
it to in the first person is a little um
un intuitive, we want to do some blending here
. I want to use vector three. Ehlert to
choose are different targets and what we're learning between.
Uh This is linear interpolation if if you don't remember
, we're basically just going to look between. Uh
I want to look between when the distance. We
want to use distances are our value for alert when
the distance between the transformed positions. This is the
difference between the camera and the first person transform.
So that would be the distance from this camera object
to the first person transform, which you can't see
because we haven't entered play mode yet, but it's
a distance between here and here. So that's the
distance you want to look up on. If it's
closer to the character's face, we want to make
the look at the normal um If it is this
is small, I want to make the look at
basically just a transformer, the camera plus the forward
of the transform. So that's just saying uh it's
a pretty simple way of saying take the camera and
look along its Z axis, that's it's forward axis
. So just let me move to the camera.
It's like saying take the camera and then look plus
one in the Z axis. So it's basically just
looking forward is the idea there and if it's further
away so anything greater than anything greater than zero,
we just want to make our look at still be
the character's head. So let's save that. We're
sorry, the characters offset, which is just our
normal look at behavior. So we're starting a new
look at here, so it's still not quite working
. And the reason for that is we haven't we
haven't actually moved the camera's target position yet. So
right now it's basically just still sitting behind the character
we really wanted to be with that first person transform
is so add one more line and we're just gonna
set the target position equal to the the position of
that first person camera that game arctic we created.
So now when you press up on the stick,
the other thing we need to do is since we're
setting a new target position here, we're going to
be overriding it here. So we need to actually
put this logic back into the used to cases of
the switch statement. So just copy this line of
code here. And just actually we need to cut
the line of code and just paste it into the
targeting behavior and we want to pace it into the
behind the camera mode. We're actually already setting it
in behind camera, so we don't need to worry
about it there. So hopefully this will work.
Let's give this a quick test and see if it
works. Okay. So I compiled set play.
Perfect. So we actually moved into that first person
camera now. Mhm. So back in unity right
now let's press forward on the stick and it looks
like we can look up and down properly. So
this is good. But the problem is we can
still run around while we're doing this and that definitely
creates a lot of weird behavior. So let's go
and add a case into our into our character controller
says if we're not in this in this first person
view, we should not if we are in the
first person view we shouldn't move the character at all
. So we'll add a case to if animator and
if the camera state is not equal to the first
person. So we have reference to the game cam
and we have reference to cam state. We need
to make sure that's a public function on public property
though it is not. So let's create that as
a property in mono develop. It's super easy to
do. You can just right click and say you
re factor and then just choose encapsulate. We only
really need to read this field so we shouldn't give
more access to the character controller than is necessary.
So we'll just do that. Yeah. And this
should now prevent it from running the character forward when
we hit up on that stick. So now we
can just look up and down. And that's good
. Problem is we can look all the way into
our body which is a little weird. So the
way we're going to fix that is just set our
limit To think 60 is probably a good number.
So we'll set that limit, you'll be able to
see how that clamp works. So now we're clamped
to these values. So if you look in the
code for the third person camera, we have this
first person local rotation is clamped between these two values
. And that's how we're getting this behavior of not
being able to look too far. So we're almost
there. But if you look at our character,
he is not facing his head. So when he's
looking it's just kind of his head is sitting there
statically which is a little weird. Um So we
want to actually move the characters neck up and down
which is actually really easy to do without making them
. This would be incredibly hard. But uh mechanism
makes it one line of code. Yeah. Okay
. I guess it's technically too but that's fine.
So we're just going to move the characters model head
by grabbing the animator component and setting the look at
rotation to look at the first person cameras position.
Plus it's forward vector. That's the same idea as
we had here where we're taking the camera's position and
the forward vector. We just want to look along
that first person object and just make sure that the
character's head is facing it. So let's turn off
the scene view follower and zoom in here. So
we're grabbing this position and we're looking along this factor
. So let's enter first person and it doesn't look
like it's working quite yet. What's what's wrong there
setting like weight, which is good, there must
be something wrong. So now that we've set this
uh look at look at position and look wait.
If we go back into the into the play view
, we can go into first person mood and look
up and down. And as you can see the
character's head is actually looking at that direction. That's
a really nice effect. Mhm. We still don't
have the ability to look left and right yet.
So how we're going to add that is just pretty
similar to how we moved to the character and the
character controller script. Uh In fixed update, we
were rotating the character using this delta rotation. So
we're gonna do the same kind of thing here and
just right after remove the character's head. We're going
to look left and right. This is pretty pretty
simple idea. We're going to make a rotation amount
. We're gonna set that equal to the the rotation
degrees per second, which let's make sure we set
this variable. So we need to grab that variable
and add that to our serialized list. So based
on this rotation degrees per second, we want to
make that as a vector three with no movement in
the in the X. Value. And we want
to make it so that we rotate the character from
zero degrees based on whether the stick is moving left
or right. You want to make this rotation degrees
per second positive or negative and want to have Z
. V. Zero as well. So rotating between
no rotation and positive rotation or negative rotation based on
the left stick. And we have to do absolute
value of the stick because otherwise the loop won't work
correctly. It'll lyric doesn't really work with negative values
. So we'll take this rotation amount and we'll create
a a quarter million rotation out of the oil rotation
. And they were going to apply that using the
attorney in multiplication into our follow transform dissertation. So
if we save this, we should be able to
see our character rotate around what's at play. We'll
go into first person mood. We can look up
and down and now we can also look left and
right by rotating our character. So that's pretty good
. If you notice actually start running the character's head
doesn't doesn't reset. It's look it's still looking at
where the camera used to be, which is kind
of weird. So we probably need to fix that
looks kind of like some exercise stuff going on there
. So the way we're going to fix that is
create a reset camera method that we're going to call
whenever we're not in the uh the first person mode
, Basically, it's just gonna set the look weight
equal to zero and reset the rotation of our camera
game. And we just want to call this method
whenever we're in the behind camera state. Mhm.
Wherever whenever we're in the targeting camera state, so
they compiled, uh we need to replay just because
sometimes, you know, it doesn't work well if
you change the script and play mode so we can
look up, look around. And when we go
back to our run mode, our character is no
longer looking at that target, which is what we
wanted. So I want to add a little bit
of polish to this. Now, we've got the
basic basics in there, but if we're looking if
our characters tells us that the side are facing the
camera, we go into first person mode, it's
a little disorienting the way that the camera moves around
. We want to have it smoothly transition into that
, both in the short of it can come down
nicely, but you see it sort of tilts down
, which is not so nice. And also if
you're to the side it doesn't really rotate into it
into place very well. So we need we need
to polish that up the way they were going to
do that as another alert and we're going to change
the look at again. And I've added a bunch
of debug, debug raising here, just so you
can get a good idea of what's actually happening.
Mhm. Yeah. Yeah. Mhm. So the
idea here is we want to take our look at
we want alert between the target position and the forward
vector. So that's basically just saying where the camera
wants to go plus looking forward. Which is usually
which just basically means when we're in play mode.
That that's just the state here because we're looking along
the target position and we're looking in the forward direction
. So you want alert between that and a second
value which is the value of the transform position which
is our camera plus the transforms forward. So that's
just looking along the cameras axis. We're going to
alert based on time, delta time. And I've
colored these vectors. This look at vector black and
you'll be able to see the first value this first
part of the alert in white and the second value
in blue or it's really science. So let's have
a look at that real fast. We'll zoom the
camera out so it's easier to see. And let's
enter first person so you can see the blue and
the white vector. The blue vector is looking along
the that's looking here, looking on this line of
code right here, looking along the first person transform
and the white is looking along the camera transform.
So as we move into this, This is going
to only run from 0-1 and then just keep going
and increasing. So it's effectively just creating a smooth
transition from looking forward at the camera, which is
what our normal behavior is as we run around to
the behavior that we want when we enter the first
person mode, which is actually looking along the first
person transform. So the idea there is just we
want to have it so that when we're here we
kind of smoothly transition in from the side, which
is a lot nicer. It just feels a lot
better. So that about does it for the first
person mode tutorial. And I think that we're going
to work next time on, perhaps polishing just to
script up a little bit, making turning a little
bit nicer and adding some nice animations into this.