﻿1
00:00:04,300 --> 00:00:05,230
‫Hello and welcome.

2
00:00:05,230 --> 00:00:12,160
‫In this lecture we are going to be looking at having some choice in our behaviour trees such that I

3
00:00:12,160 --> 00:00:20,500
‫can have an enemy run towards me and if he loses sight of me, he comes to my last known location doing

4
00:00:20,500 --> 00:00:24,250
‫basically two behaviors a chase and then an investigate behavior.

5
00:00:24,250 --> 00:00:26,080
‫Let's dive in and see how that's achievable.

6
00:00:26,080 --> 00:00:27,370
‫Using behavior trees.

7
00:00:28,470 --> 00:00:34,590
‫So while this patrolling behavior is very instructive, it's not really the kind of behavior that we

8
00:00:34,590 --> 00:00:35,520
‫want to implement.

9
00:00:35,700 --> 00:00:39,300
‫What we'd rather have is something along the following lines.

10
00:00:39,300 --> 00:00:44,820
‫When we can see the player, we go and move as close to them as we possibly can.

11
00:00:45,240 --> 00:00:51,900
‫And when the player goes out of sight, then we try and move to the last known location of the player

12
00:00:51,900 --> 00:00:52,670
‫to find them.

13
00:00:52,680 --> 00:00:58,470
‫And once we have exhausted that option, maybe we go back to a different location, or maybe we just

14
00:00:58,470 --> 00:01:00,390
‫stay there for now.

15
00:01:00,840 --> 00:01:02,430
‫So how can we achieve this?

16
00:01:02,460 --> 00:01:05,910
‫Well, at the moment, we've got no way of achieving this with a sequence of actions.

17
00:01:05,910 --> 00:01:09,240
‫We need to make a choice based on the data that we have available.

18
00:01:09,240 --> 00:01:15,270
‫We need to choose between whether we can see the player or whether we can't, whether we've got a last

19
00:01:15,270 --> 00:01:18,680
‫known player location or not, that sort of thing.

20
00:01:18,720 --> 00:01:24,060
‫So to do this, we need a new type of node in the behaviour tree called a selector node.

21
00:01:24,060 --> 00:01:29,280
‫So if we right click and look at our composites, one of the options there is the selector.

22
00:01:29,430 --> 00:01:33,330
‫Now the selector as opposed to the sequence runs thusly.

23
00:01:33,360 --> 00:01:40,740
‫If you have a bunch of tasks underneath the selector, it is going to run until the first one succeeds.

24
00:01:40,740 --> 00:01:45,420
‫And basically it's expecting all of them to fail until one of them succeeds.

25
00:01:45,660 --> 00:01:48,210
‫Now the sequence did the opposite.

26
00:01:48,210 --> 00:01:50,460
‫It runs all of them until one of them fails.

27
00:01:50,640 --> 00:01:52,820
‫So why is that useful?

28
00:01:52,830 --> 00:01:56,640
‫Why is it useful that the selector runs one of them and still one of them succeeds?

29
00:01:56,640 --> 00:02:01,140
‫Because basically we want it to choose the first option that is viable.

30
00:02:01,830 --> 00:02:06,840
‫Now, the way we're going to do this is not by actually running tasks underneath the selector, but

31
00:02:06,840 --> 00:02:08,970
‫running sequences underneath the selector.

32
00:02:08,970 --> 00:02:12,360
‫So at the root level, we're going to be doing a selector node.

33
00:02:12,570 --> 00:02:17,160
‫And then beneath that, let's just move this sequence aside and create other sequences.

34
00:02:17,160 --> 00:02:23,220
‫We're going to have one sequence over here, and what we can do is we can actually rename the sequence

35
00:02:23,220 --> 00:02:31,080
‫from being sequence to something like Chase, and then we can add in another sequence here, which is

36
00:02:31,080 --> 00:02:35,280
‫going to be along of the lines of investigate.

37
00:02:35,990 --> 00:02:41,600
‫And these are basically our two behaviors that we want to be able to choose between.

38
00:02:42,140 --> 00:02:49,210
‫And in order to make them fail, we can add things to nodes called decorators.

39
00:02:49,220 --> 00:02:55,130
‫So if you right click on a node and go add decorator, you can see here there's a bunch of options here

40
00:02:55,370 --> 00:02:59,500
‫and they basically change the way this node works.

41
00:02:59,510 --> 00:03:00,920
‫Then they can do that in a number of ways.

42
00:03:00,920 --> 00:03:05,870
‫For example, we've got this conditional loop which allows you to loop through all the actions again

43
00:03:05,870 --> 00:03:08,960
‫in the sequence as many times as this conditional is correct.

44
00:03:09,110 --> 00:03:15,830
‫We've got other things here, like a cone check, which is about visibility and other such lovely things.

45
00:03:15,830 --> 00:03:17,990
‫We got just a pure loop.

46
00:03:18,110 --> 00:03:22,910
‫We've got a time limit, so it's a can only we can only stay inside this sequence for a certain amount

47
00:03:22,910 --> 00:03:23,450
‫of time.

48
00:03:23,450 --> 00:03:27,200
‫Basically lots of things that modify the behavior of this sequence.

49
00:03:27,200 --> 00:03:33,320
‫But the one that we are interested in is the blackboard, because this is a blackboard condition.

50
00:03:33,320 --> 00:03:38,150
‫And as you can see from the writing underneath of it, the default is something along the lines of is

51
00:03:38,150 --> 00:03:39,950
‫this self actor set?

52
00:03:40,130 --> 00:03:47,000
‫And if this is not set, then automatically this node and everything underneath it will fail, which

53
00:03:47,000 --> 00:03:51,050
‫means that our selector will go on to option two, which is investigate.

54
00:03:51,170 --> 00:03:53,840
‫So in this case, we actually want to change this up.

55
00:03:53,840 --> 00:03:55,220
‫We want to change how this works.

56
00:03:55,220 --> 00:04:02,420
‫So our player location, we want this to be such that it is only set when the player is visible.

57
00:04:02,420 --> 00:04:10,310
‫And then we want to add in a new variable here again, a vector which is going to be the last known

58
00:04:10,310 --> 00:04:16,250
‫player location and the last known player location when the player is visible is going to be the same.

59
00:04:16,400 --> 00:04:22,460
‫But once the player becomes invisible, the player location gets unset and the last known player location

60
00:04:22,460 --> 00:04:24,080
‫is where we're going to want to go.

61
00:04:24,590 --> 00:04:30,290
‫So we can do this by going to our Blackboard Base condition and just changing it to being the query

62
00:04:30,290 --> 00:04:35,330
‫to be Yes is set, but the thing that we want to be is set is the player location.

63
00:04:35,330 --> 00:04:41,960
‫So if the player location is set, then we're going to give Chase and we're going to give Chase by doing

64
00:04:41,960 --> 00:04:48,020
‫basically just a move to and we're going to move to the player location like.

65
00:04:48,020 --> 00:04:51,770
‫So now we're not doing much else under this sequence.

66
00:04:51,770 --> 00:04:58,490
‫So in actual fact, you could put this blackboard condition directly on the move too, but because we

67
00:04:58,490 --> 00:05:02,390
‫might want to do other things such as shooting, I'm going to leave it as a sequence for now.

68
00:05:02,510 --> 00:05:04,070
‫And then we've got this investigate.

69
00:05:04,070 --> 00:05:10,490
‫Investigate is basically also going to do a move, too, but it's going to move to instead of moving

70
00:05:10,490 --> 00:05:16,250
‫to the player location, it's going to move to the last known player location.

71
00:05:16,490 --> 00:05:23,030
‫And you can see we don't have a condition on that because this falls through if this condition fails.

72
00:05:23,300 --> 00:05:29,240
‫One important thing to note about these blackboard conditions is that by default, once we have made

73
00:05:29,240 --> 00:05:34,130
‫the decision to start executing this node, we're not going to reevaluate that.

74
00:05:34,130 --> 00:05:39,830
‫So if for some reason we lose sight of the player while we're moving to that player's location, we're

75
00:05:39,830 --> 00:05:41,810
‫going to keep trying to get there.

76
00:05:41,960 --> 00:05:49,610
‫So if we want it to be able to abort the execution of this node, then there's an option for that.

77
00:05:49,610 --> 00:05:53,780
‫If you go to the flow control, there's notified observers and there is underneath it.

78
00:05:53,780 --> 00:05:56,270
‫Observer aborts at the moment set to none.

79
00:05:56,510 --> 00:05:58,700
‫But you can select from a couple of options.

80
00:05:59,180 --> 00:06:00,830
‫You can set it to self.

81
00:06:00,830 --> 00:06:07,850
‫So this is saying if this condition suddenly becomes false, then stop whatever you are doing and reevaluate

82
00:06:07,850 --> 00:06:09,800
‫your selector and see.

83
00:06:09,800 --> 00:06:11,780
‫Maybe we now need to do the investigate.

84
00:06:11,780 --> 00:06:18,530
‫Note The other option here is lower priority and you can see that it's changed what's highlighted here.

85
00:06:18,530 --> 00:06:24,440
‫It's saying if suddenly this blackboard condition became true, stop whatever else we were doing and

86
00:06:24,440 --> 00:06:27,050
‫start executing this chase condition.

87
00:06:27,260 --> 00:06:29,840
‫And then the final option is both.

88
00:06:29,840 --> 00:06:31,160
‫And this is the one that we want.

89
00:06:31,160 --> 00:06:37,220
‫Basically, it's saying that this blackboard based condition, if it becomes true, we start executing

90
00:06:37,220 --> 00:06:38,690
‫this sequence immediately.

91
00:06:38,690 --> 00:06:44,150
‫If it becomes false, we stop executing it immediately or stop executing whatever else was going on.

92
00:06:44,150 --> 00:06:51,380
‫We just basically want to always go and do whatever path is dictated by this blackboard condition.

93
00:06:51,380 --> 00:06:56,750
‫So hopefully that makes sense that the observer aborts stop things in action, otherwise it will wait

94
00:06:56,750 --> 00:06:59,960
‫until the action is finished before re-evaluating.

95
00:07:00,380 --> 00:07:07,130
‫So really, now we want to go ahead and implement our last known play location and player location,

96
00:07:07,130 --> 00:07:13,100
‫because at the moment, if we go over to our C++ and give ourselves a little bit more room, then you

97
00:07:13,100 --> 00:07:16,370
‫can see that we're only setting this player location in Begin Play.

98
00:07:16,370 --> 00:07:21,440
‫Ideally, we'd be doing this every time we have line of sight to our player pawn, so we can actually

99
00:07:21,440 --> 00:07:23,780
‫uncomment our line of sight code here.

100
00:07:23,960 --> 00:07:27,470
‫And we probably want to uncomment the else code as well.

101
00:07:27,470 --> 00:07:32,330
‫But we're not in this case going to be clearing focus and stopping movement directly.

102
00:07:32,330 --> 00:07:35,570
‫I can go ahead and remove these entirely because.

103
00:07:35,640 --> 00:07:37,830
‫That's not the way we're doing things at the moment.

104
00:07:38,010 --> 00:07:47,160
‫Instead, what we want to be doing, if I remove the code, is we want to be in here setting the player

105
00:07:47,160 --> 00:07:48,200
‫location.

106
00:07:48,210 --> 00:07:59,820
‫We also want to be setting the last known location there and in else we want to clear the player location.

107
00:08:00,210 --> 00:08:07,860
‫Now to do that, we have got a function available to us which is instead of the set value as vector,

108
00:08:07,860 --> 00:08:17,250
‫if we go ahead and open our blackboard component, there is a clear value and this just takes the f

109
00:08:17,250 --> 00:08:22,800
‫name, doesn't need to take a type or anything or because we're just completely erasing whatever was

110
00:08:22,800 --> 00:08:24,090
‫in that variable.

111
00:08:24,480 --> 00:08:28,140
‫So here I've got the challenge for you to fill out our tick set.

112
00:08:28,140 --> 00:08:35,010
‫The two variables when line of sight, basically fill out this first bit of the if statement and then

113
00:08:35,010 --> 00:08:39,270
‫clear the player location when we have the alt.

114
00:08:39,270 --> 00:08:42,210
‫So when we lose line of sight, we don't have a player location anymore.

115
00:08:42,240 --> 00:08:48,510
‫Reduce the speed of the enemy that's in the world so that you can get away from him more easily.

116
00:08:48,510 --> 00:08:54,780
‫And then check the functionality, check that you're able to hide behind a corner and that he goes to

117
00:08:54,780 --> 00:08:57,150
‫the last known location to try and find you.

118
00:08:57,240 --> 00:08:59,460
‫Pause the video and have a go at this.

119
00:09:00,490 --> 00:09:00,820
‫Okay.

120
00:09:00,820 --> 00:09:01,420
‫Welcome back.

121
00:09:01,420 --> 00:09:02,560
‫So let's give this a shot.

122
00:09:02,560 --> 00:09:04,240
‫First of all, we're setting the play location.

123
00:09:04,240 --> 00:09:07,240
‫I'm going to move that out of begin play and move it here instead.

124
00:09:07,330 --> 00:09:12,880
‫So we're going to set the player location to we need to be getting the player pawn here and tick again.

125
00:09:12,880 --> 00:09:19,180
‫So I'll uncomment that line and then we're doing exactly the same thing, exactly the same line of code

126
00:09:19,180 --> 00:09:22,000
‫for our last known player location here.

127
00:09:22,000 --> 00:09:28,060
‫So let's go to our blackboard and just make sure we copy it so we get exactly the same name and then

128
00:09:28,060 --> 00:09:33,160
‫we just want to clear that's the final thing is to clear our player location here.

129
00:09:33,160 --> 00:09:39,610
‫So it's going to be clear value and it's going to take this text player location as the value that we're

130
00:09:39,610 --> 00:09:41,980
‫trying to clear at the end.

131
00:09:42,280 --> 00:09:46,870
‫And we can go ahead and compile and see if this works.

132
00:09:48,640 --> 00:09:50,530
‫Well compile was a successful.

133
00:09:50,530 --> 00:09:55,870
‫The other thing I said to do to make our debugging easier was to select the enemy and we can go and

134
00:09:55,870 --> 00:10:03,880
‫change their speed by going down to their movement component and finding the walking and finding their

135
00:10:03,880 --> 00:10:04,360
‫speed.

136
00:10:04,360 --> 00:10:07,270
‫So Max Walk speed is 600 here.

137
00:10:07,300 --> 00:10:11,470
‫Let's set it down to 400 so we can easily get away from them.

138
00:10:11,470 --> 00:10:15,220
‫They're going to walk a bit slow and go ahead and play.

139
00:10:15,220 --> 00:10:16,720
‫They are walking towards us slowly.

140
00:10:16,720 --> 00:10:18,010
‫We can run away.

141
00:10:18,040 --> 00:10:22,840
‫We hide behind a corner and here they come looking for us each time.

142
00:10:22,840 --> 00:10:28,120
‫But hopefully if we hide behind two corners, they won't be able to find us.

143
00:10:28,120 --> 00:10:31,210
‫So I hide there, hide here, hide here.

144
00:10:31,210 --> 00:10:35,350
‫And he's going to go and investigate at the last known location, you see, he's just poked his head

145
00:10:35,350 --> 00:10:39,730
‫around the corner, but then he's stuck there because he doesn't know what to do.

146
00:10:39,790 --> 00:10:46,960
‫And if we were to go and have a look at our behavior tree and just put this over to one side and the

147
00:10:46,960 --> 00:10:50,110
‫game to the other and give myself a little bit of room.

148
00:10:50,200 --> 00:10:54,940
‫Then if we have a look at the behavior tree, we can see it's kind of jazzing around here because it

149
00:10:54,940 --> 00:10:56,680
‫can't do either of them.

150
00:10:56,680 --> 00:11:00,400
‫It's trying to move to the last known location that's succeeding.

151
00:11:00,400 --> 00:11:01,930
‫So it's getting a bit stuck here.

152
00:11:01,930 --> 00:11:05,980
‫But if I come into view, you can see he's moving towards me.

153
00:11:05,980 --> 00:11:11,830
‫If he loses sight of me, then he goes over to the investigate condition.

154
00:11:11,830 --> 00:11:12,760
‫So lose a sight.

155
00:11:12,760 --> 00:11:14,110
‫He's going to investigate.

156
00:11:14,110 --> 00:11:18,130
‫And then he comes and sees me and then he goes back to chasing me.

157
00:11:18,130 --> 00:11:20,800
‫So this behavior is actually working.

158
00:11:20,800 --> 00:11:29,170
‫Now we're able to do a choice between trying to chase and trying to investigate based on this blackboard

159
00:11:29,170 --> 00:11:29,710
‫behavior.

160
00:11:29,710 --> 00:11:37,210
‫Let's just change the name of this blackboard to behavior here to can see player question mark.

161
00:11:37,210 --> 00:11:38,890
‫So that's going to be much easier to read.

162
00:11:38,890 --> 00:11:43,990
‫Now we've got this selector can see the player, then we should chase, otherwise we should investigate

163
00:11:43,990 --> 00:11:49,120
‫and we can delete this sequence over here because that is no longer in use.

164
00:11:49,150 --> 00:11:54,730
‫So hopefully now you've got a bit of a better understanding of how behavior trees can be linked together

165
00:11:54,730 --> 00:12:01,690
‫to create choice and sequence and put lots of tasks together to make more complex behaviors really easily.

166
00:12:01,690 --> 00:12:08,020
‫In the next lecture, we're going to be looking at how we can make our own custom tasks in C++ so that

167
00:12:08,020 --> 00:12:10,510
‫we can get some shooting action.

168
00:12:10,510 --> 00:12:11,980
‫I'll see you in the next video.

