1
00:00:03,770 --> 00:00:08,510
In this lecture, we're going to make the player feel the weight of being hit by adding some screen

2
00:00:08,510 --> 00:00:09,890
shake to our camera.

3
00:00:10,690 --> 00:00:13,660
So this is an effect relating to our camera.

4
00:00:13,660 --> 00:00:19,360
So let's create a new script, first of all, and let's go into our scripts folder and create a new

5
00:00:19,360 --> 00:00:22,150
C-sharp script called Camera Shake.

6
00:00:23,170 --> 00:00:28,410
And let's apply this to our main camera and essentially how this script is going to work.

7
00:00:28,420 --> 00:00:33,680
It's going to take the current position of the camera and just move it around every frame.

8
00:00:33,700 --> 00:00:35,710
So let's open up our script.

9
00:00:36,010 --> 00:00:41,070
Let's clean up our comments above, start and delete our update method entirely.

10
00:00:41,080 --> 00:00:44,110
And this effect is going to be controlled by two parameters.

11
00:00:44,110 --> 00:00:48,000
So let's create some serialized fields of type float.

12
00:00:48,010 --> 00:00:51,040
The first one is going to be the shake duration.

13
00:00:51,040 --> 00:00:53,320
So how long is the effect going to last?

14
00:00:53,320 --> 00:00:56,590
And we can default that to maybe 1/2 for now.

15
00:00:56,920 --> 00:01:03,070
And the second is going to be of type float and we're going to call it the shake magnitude.

16
00:01:03,070 --> 00:01:05,500
So how far is the camera going to move?

17
00:01:05,530 --> 00:01:10,600
And again, by default, we'll set this up at point five and we can always fine tune and adjust these

18
00:01:10,600 --> 00:01:11,470
numbers later.

19
00:01:11,620 --> 00:01:16,060
Finally, for our variables, we're going to want to know the initial position of our camera, because

20
00:01:16,060 --> 00:01:20,070
once we've finished moving it around, we want to set it back to where it started.

21
00:01:20,080 --> 00:01:24,010
So let's take a vector three called initial position.

22
00:01:24,970 --> 00:01:31,570
And in our stop method, we're going to set our initial position equal to our transform position.

23
00:01:32,710 --> 00:01:36,750
Now, to get this effect working, we're going to be using a CO routine.

24
00:01:36,760 --> 00:01:39,880
This CO routine is then going to be called from another script.

25
00:01:39,880 --> 00:01:46,690
So let's set up that method first and have a public void and we'll call this one play.

26
00:01:46,690 --> 00:01:53,530
So we'll have camera shake play or this is going to do is start a CO routine and we'll call this CO

27
00:01:53,530 --> 00:01:54,820
routine shake.

28
00:01:55,660 --> 00:01:58,420
Now let's create our shake co routine.

29
00:01:58,420 --> 00:02:01,960
So we've got an AI enumerator called Shake.

30
00:02:02,530 --> 00:02:06,400
And writing this CO routine is mostly going to be a challenge for you.

31
00:02:06,400 --> 00:02:11,950
But let's just look at the logic for moving the camera to a random position to start with.

32
00:02:11,980 --> 00:02:19,390
So we're going to be moving our transform position and this is going to be equal to our initial position,

33
00:02:19,390 --> 00:02:24,580
plus a random dot inside unit circle.

34
00:02:24,580 --> 00:02:29,590
And notice here we've got an inside unit circle and an inside unit sphere.

35
00:02:29,800 --> 00:02:32,920
Since our game is 2D, the third axis doesn't really matter.

36
00:02:32,920 --> 00:02:36,640
So let's go with an inside unit circle and a unit circle.

37
00:02:36,640 --> 00:02:40,150
If you're not aware, it's just a circle with a radius of one.

38
00:02:40,150 --> 00:02:46,540
So to give us a bit more control, let's also multiply that by our shake magnitude and this will change

39
00:02:46,540 --> 00:02:48,220
the radius of that circle.

40
00:02:48,460 --> 00:02:53,290
Now this is giving us a red squiggly, and if we hover over it, it's saying that it's having trouble

41
00:02:53,290 --> 00:02:59,860
adding a vector three and a vector to remember our position is a vector three and our random inside

42
00:02:59,860 --> 00:03:01,690
unit circle is a vector two.

43
00:03:01,690 --> 00:03:09,790
So we could either change this to inside units fear or we could cast this to a vector three and to cast

44
00:03:09,790 --> 00:03:14,440
a variable, we're just placing it inside parentheses before the thing we're trying to cast.

45
00:03:14,440 --> 00:03:20,590
And this will tell the compiler to treat this value as a vector three rather than a vector two.

46
00:03:20,590 --> 00:03:26,200
And in this case, the third Z component that isn't in our vector two is just going to be set as zero

47
00:03:26,200 --> 00:03:27,220
in a vector three.

48
00:03:27,550 --> 00:03:32,140
So to explain this line in a little bit more detail, let's break it down in a slide.

49
00:03:32,290 --> 00:03:38,260
We start off with the camera in its initial position and then add a random point within a circle.

50
00:03:38,290 --> 00:03:43,480
This circle is starting with a magnitude of one being a unit circle, but then we're multiplying that

51
00:03:43,480 --> 00:03:48,190
by the shape magnitude, which gives us control over the area in which our camera can move.

52
00:03:48,310 --> 00:03:53,800
And then what we want to do is take our current line of code and place it into a loop so that every

53
00:03:53,800 --> 00:03:56,890
frame we pick a new position for our camera to be.

54
00:03:56,890 --> 00:04:01,210
And if we move the camera around quick enough, it'll make it look like the screen is shaking and not

55
00:04:01,210 --> 00:04:03,280
just being displaced every now and again.

56
00:04:03,280 --> 00:04:08,260
Then, once the loop has finished, we want to place our camera back into its starting location.

57
00:04:08,410 --> 00:04:11,380
So this now brings us onto your challenge.

58
00:04:11,380 --> 00:04:14,680
I want you to complete our shake routine.

59
00:04:14,920 --> 00:04:19,899
If you'd like a couple of hints, then the camera should shake for the shake duration.

60
00:04:19,899 --> 00:04:22,420
So we're going to be adding some kind of loop in here.

61
00:04:22,420 --> 00:04:27,970
And you may or may not want a temporary variable to help control this loop condition on every loop.

62
00:04:27,970 --> 00:04:33,940
Once we've changed the position, we're going to want to yield control until the next frame, and we're

63
00:04:33,940 --> 00:04:38,490
used to waiting 4 seconds, but have a look and see what else we can wait for.

64
00:04:38,620 --> 00:04:44,590
Then once the shake duration has expired and our loop complete, we want to go ahead and reset the camera's

65
00:04:44,590 --> 00:04:46,690
position to its initial position.

66
00:04:46,690 --> 00:04:49,570
So pause the video now and give that a go.

67
00:04:55,320 --> 00:04:55,620
Okay.

68
00:04:55,620 --> 00:04:56,530
Welcome back.

69
00:04:56,550 --> 00:04:59,590
So let's create the loop, first of all.

70
00:04:59,610 --> 00:05:05,250
And to help with this, I'm going to create a temporary variable of type float called elapsed time.

71
00:05:06,140 --> 00:05:08,570
I will set this to zero to start with.

72
00:05:08,900 --> 00:05:14,660
Then for a loop I'm going to use a while loop because we don't know exactly how many iterations we're

73
00:05:14,660 --> 00:05:15,530
going to need.

74
00:05:15,650 --> 00:05:24,710
So let's say while the elapsed time is less than our shake duration, then we want to go ahead and continuously

75
00:05:24,710 --> 00:05:27,440
move our camera position to stop ourselves.

76
00:05:27,440 --> 00:05:29,180
Getting into an infinite loop.

77
00:05:29,180 --> 00:05:32,720
Though, we're going to need to increment our elapsed time every loop.

78
00:05:32,720 --> 00:05:38,780
So let's say elapsed time plus equals our time dot delta time.

79
00:05:38,930 --> 00:05:45,620
And then finally we're going to yield return a new wait for end of frame.

80
00:05:45,620 --> 00:05:50,180
So that will wait for the end of frame before coming back to our routine to check if it needs to do

81
00:05:50,180 --> 00:05:51,020
anything else.

82
00:05:51,170 --> 00:05:57,740
Lastly, once that loop has completed and our elapsed time is greater than or equal to our shake duration,

83
00:05:57,740 --> 00:06:03,680
we can go ahead and reset our transform position to be equal to our initial position.

84
00:06:03,800 --> 00:06:07,040
So that's a very basic camera shaking script.

85
00:06:07,040 --> 00:06:10,370
And now let's look at where to call our play method.

86
00:06:10,490 --> 00:06:14,060
Well, I think a good place to this would again be in our health script.

87
00:06:14,060 --> 00:06:17,330
So let's jump over to our health script at the top.

88
00:06:17,330 --> 00:06:18,800
Let's create some variables.

89
00:06:18,800 --> 00:06:23,600
First of all, we're going to need a camera shake called Camera Shake.

90
00:06:24,320 --> 00:06:30,890
And I'm also going to add a serialized field here of Type Ball to check whether we should apply the

91
00:06:30,890 --> 00:06:31,790
camera shake.

92
00:06:32,000 --> 00:06:37,670
Because remember, the health script is attached to both our player and our enemies, and we don't really

93
00:06:37,670 --> 00:06:42,680
want this camera shake going off whenever we hit anything because it's going to be a bit too much.

94
00:06:42,680 --> 00:06:48,170
So instead, we're going to limit it to just the player and this boolean will let us switch it off for

95
00:06:48,170 --> 00:06:48,950
our enemies.

96
00:06:49,340 --> 00:06:55,100
So with those variables set up, let's grab a reference to our camera, shake script, and we can do

97
00:06:55,100 --> 00:07:01,910
this in our wake method so we can say camera shake and to find the component, we could go and find

98
00:07:01,910 --> 00:07:03,200
the object in the scene.

99
00:07:03,200 --> 00:07:10,250
But remember, the camera has a handy tag attached to it and this tag allows us to say camera dot,

100
00:07:10,250 --> 00:07:15,740
main, dot, get component, and the component we want is our camera shake.

101
00:07:16,430 --> 00:07:22,130
So that's just another way of doing things for our camera because this camera domain already has a find

102
00:07:22,160 --> 00:07:23,990
object of type built into it.

103
00:07:24,350 --> 00:07:28,010
So now let's decide where to actually call this shaking camera.

104
00:07:28,040 --> 00:07:32,630
And again, like how we've got our play hit effect in our on trigger enter.

105
00:07:32,630 --> 00:07:36,020
We're going to do a very similar thing with a camera shake.

106
00:07:36,230 --> 00:07:39,620
So we're going to create a new method called Shake Camera.

107
00:07:40,010 --> 00:07:44,840
And then if we go to the bottom of our script, let's create a new void.

108
00:07:44,840 --> 00:07:46,040
Shake camera.

109
00:07:48,490 --> 00:07:54,040
And in here first of all, we want to check that our camera shake does not equal nul so that we've managed

110
00:07:54,040 --> 00:08:00,190
to find it on the camera and we want to check whether we should be applying this camera shake at all.

111
00:08:00,520 --> 00:08:04,900
If all of that is fine, then we can ask our camera shake to play.

112
00:08:05,710 --> 00:08:09,100
So let's save up our script and test this out in unity.

113
00:08:09,890 --> 00:08:15,530
We can see here on our camera, we've got our two variables for our shake duration and our shake magnitude.

114
00:08:15,920 --> 00:08:21,410
And if we head over to our prefabs and look at our enemy, we want to make sure that the apply camera

115
00:08:21,410 --> 00:08:23,810
shake is switched off in its health script.

116
00:08:24,290 --> 00:08:27,290
And for our player, we want to go and make sure that it's on.

117
00:08:28,500 --> 00:08:34,400
Now, if we go ahead and hit play to test this out, let's get hit by an enemy and I'll screen shake.

118
00:08:34,400 --> 00:08:35,490
It gets applied.

119
00:08:35,520 --> 00:08:40,380
The effect is way too violent though, so let's tone it down just a tad.

120
00:08:40,620 --> 00:08:42,090
So let's come out of play mode.

121
00:08:42,120 --> 00:08:48,510
Let's go over to our main camera and let's maybe reduce the camera shake duration to around half a second

122
00:08:48,510 --> 00:08:51,600
and the magnitude two around 0.25.

123
00:08:52,470 --> 00:08:54,300
Let's play again and test that out.

124
00:08:56,440 --> 00:08:59,160
And flat screen shake is now much more subdued.

125
00:08:59,170 --> 00:09:04,750
But notice when we try and hit our enemies, the screen shake doesn't get applied only when we get hit

126
00:09:04,750 --> 00:09:05,440
by them.

127
00:09:05,830 --> 00:09:10,270
And with that, we now have a nice extra effect in our game to help the player know when they've been

128
00:09:10,270 --> 00:09:11,500
struck by an enemy.

129
00:09:11,530 --> 00:09:16,990
Now, as a word of warning, I would caution you with using this effect too much, because it can make

130
00:09:16,990 --> 00:09:19,830
players feel a little bit sick if it goes on for too long.

131
00:09:19,840 --> 00:09:23,640
And this is also a very simplistic version of a camera shake effect.

132
00:09:23,650 --> 00:09:28,810
If you'd like to play around with this effect and create something a bit more robust, then in the resources.

133
00:09:28,810 --> 00:09:32,970
I've linked to a fantastic GDC talk on this very subject.

134
00:09:32,980 --> 00:09:37,180
We went with this version in our project because it's fairly easy to implement and there's not really

135
00:09:37,180 --> 00:09:38,650
much math involved.

136
00:09:38,650 --> 00:09:43,450
But if you are that way inclined and you enjoy some math, feel free to check out that talk because

137
00:09:43,450 --> 00:09:46,630
it goes through some of the more complicated math that you might need.

138
00:09:46,630 --> 00:09:51,850
So congratulations on implementing this version of a screen shake effect, and I'll see you in the next

139
00:09:51,850 --> 00:09:52,480
lecture.

