﻿1
00:00:04,680 --> 00:00:05,640
‫こんにちは､ ようこそ｡

2
00:00:05,640 --> 00:00:11,910
‫このレクチャーでは､ 自分のレベルにいる敵をすべて倒せるように､ 勝利条件を作っていくことになります｡

3
00:00:11,910 --> 00:00:14,220
‫そして､ このフロントガラスが表示されるのです｡

4
00:00:14,220 --> 00:00:14,780
‫ばんざーい！！（笑

5
00:00:14,790 --> 00:00:16,560
‫さっそく潜入してみましょう｡

6
00:00:17,800 --> 00:00:22,210
‫だから､ このゲームで実際にプレイヤーが勝てるようにしたいんだ｡

7
00:00:22,210 --> 00:00:23,740
‫今のところ､ それはできません｡

8
00:00:23,950 --> 00:00:25,090
‫では､ どうすればいいのか？

9
00:00:25,120 --> 00:00:27,070
‫まあ､ いろいろなやり方があるでしょうね｡

10
00:00:27,070 --> 00:00:33,370
‫そのひとつが､ Pawn Killedが呼ばれたときに､ ポーンがプレイヤーコントローラーではなく､ AIだった場合です｡

11
00:00:33,400 --> 00:00:40,090
‫世界に何人のAIがいるかという変数から､ 何人殺さなければならないかを引くことができる｡

12
00:00:40,090 --> 00:00:43,830
‫そして､ それがゼロになったとき､ プレイヤーに有利な形でゲームを終了させることができるのです｡

13
00:00:43,840 --> 00:00:51,070
‫ただ､ その場合､ 世界に敵が何人いるのかを2か所に分けて考えなければならないので､ ちょっともろいと思いますね｡

14
00:00:51,070 --> 00:00:55,450
‫本来は､ ゲームモードにも必要ですが､ 敵を配置する際にもワールドに必要で､

15
00:00:55,450 --> 00:00:59,530
‫この2つが同期していないと､ 問題が発生するのです｡

16
00:00:59,740 --> 00:01:05,740
‫ポーンが殺されるたびに世界中の敵を数え､ AI全員の頭数を数え直し､

17
00:01:05,740 --> 00:01:13,060
‫どれがまだ生きているか確認しよう､ というのが私の好む方法です｡

18
00:01:13,060 --> 00:01:16,600
‫もし､ まだ生きている人がいるならば､ まだゲームを終わらせるつもりはない｡

19
00:01:16,600 --> 00:01:21,460
‫基本的にゲームオーバーにはなりませんが､ 全員死んでいて､ プレイコントローラーが死んでいなければ､

20
00:01:21,460 --> 00:01:23,110
‫プレイヤーの勝利となります｡

21
00:01:23,530 --> 00:01:30,070
‫そのためには､ プレーヤーコントローラーが死んでいるかどうかを問い合わせる方法が必要です｡

22
00:01:30,070 --> 00:01:32,140
‫すみません､ AIコントローラのことです｡

23
00:01:32,290 --> 00:01:34,030
‫では､ 撮影者を探してみましょう｡

24
00:01:34,030 --> 00:01:35,260
‫AIコントローラー｡

25
00:01:36,370 --> 00:01:42,400
‫そして､ ここでやりたいことは､ 死んでいるかどうかを問い合わせることができる新しいパブリックメソッドを作ることです｡

26
00:01:42,400 --> 00:01:49,330
‫つまり､ ボールは基本的に死んでいて､ それが呼び出されたときにコントローラで実際に起こっていることを変えてはいけないから､

27
00:01:49,330 --> 00:01:52,930
‫コンテストになるんだ､ ということをやろうと思っています｡

28
00:01:53,440 --> 00:01:55,780
‫そして､ 先に実装を作成することができます｡

29
00:01:56,510 --> 00:02:01,780
‫今､ 私たちがコントロールすべきなのは......死んだかどうかを教えてくれるものです｡

30
00:02:01,790 --> 00:02:07,760
‫もう一度見てみると､ シューターのキャラクターは......｡

31
00:02:07,760 --> 00:02:12,160
‫覚えておいて､ 我々はすでにこれが死んでいる機能することはできません｡

32
00:02:12,170 --> 00:02:17,390
‫つまり､ 本質的にやりたいことは､ 私が今コントロールしているシューターにリクエストを渡すことだけなのです｡

33
00:02:17,390 --> 00:02:17,990
‫はい｡

34
00:02:17,990 --> 00:02:23,780
‫ひとつは､ KMLのゲームモードで､ コントローラーを手に取り､ 操作しているものを手に取り､

35
00:02:23,780 --> 00:02:30,380
‫キャストして､ それが死んでいるかどうかをチェックすることができます｡

36
00:02:30,380 --> 00:02:36,410
‫というのも､ 突然死の計算方法が変わったり､ AIコントローラーが異なる種類のものを操作するようになったりすると､

37
00:02:36,410 --> 00:02:46,880
‫突然ゲームモードを変更しなければならなくなり､ 意味がなくなってしまうからです｡

38
00:02:46,880 --> 00:02:52,580
‫だから､ これをやって､ AI制御の内部で受け渡しをやったほうが､ よりロバストになるんです｡

39
00:02:52,580 --> 00:02:58,790
‫他人のクラスの内部をいじくり回さずに済むので､ 一般に､ 物事が変わるタイミングを制限することができ､

40
00:02:58,790 --> 00:03:06,920
‫触ったり更新したり変更したりしなければならないクラスの数を制限することができます｡

41
00:03:07,400 --> 00:03:13,160
‫だから､ 私たちがやりたいのは､ シューターキャラクターであることを確認するための......キャスティングなんです｡

42
00:03:13,160 --> 00:03:14,450
‫では､ キャストをやってみましょう｡

43
00:03:14,690 --> 00:03:17,270
‫シューターになるんです｡

44
00:03:18,040 --> 00:03:18,970
‫キャラクター

45
00:03:19,360 --> 00:03:25,960
‫そして､ このようにシューターキャラクターを知るために､ アイコントロールの先頭でハッシュインクルードを行う必要がありそうですね｡

46
00:03:26,110 --> 00:03:37,000
‫そして､ キャストをgetして -- これを変数に格納したいので､ シューターとします｡

47
00:03:37,000 --> 00:03:42,670
‫キャラクターポインターは､ コントロールされていると呼ぶことにしましょう｡

48
00:03:43,830 --> 00:03:44,730
‫キャラクター

49
00:03:46,030 --> 00:03:52,390
‫characterというのは､ すでにAIコントローラの変数になっているので､ これを呼ぶわけにはいきません｡ 行の最後にセミコロンをつけて､

50
00:03:52,390 --> 00:03:56,740
‫これがヌルかどうかをチェックすることにします｡

51
00:03:56,980 --> 00:04:04,980
‫つまり､ 制御文字がヌルポインタと等しくない場合､ それが死んでいるかどうか､ その状態を問い合わせることができるはずなのです｡

52
00:04:04,990 --> 00:04:10,180
‫だから､ その制御されたキャラクターを返すことができるはずです｡

53
00:04:11,100 --> 00:04:12,480
‫死んだ｡

54
00:04:12,810 --> 00:04:18,870
‫基本的に､ 制御文字がシューター文字である場合は､ 制御文字へのリクエストで転送します｡

55
00:04:18,990 --> 00:04:22,350
‫しかし､ ここではreturn文がないことに注意してください｡

56
00:04:22,350 --> 00:04:29,130
‫もう一つのケースは､ 戻り値がvoidでなければ必ずreturnになるようなステートメントを用意する必要があります｡

57
00:04:29,130 --> 00:04:37,950
‫そこで､ if文の中でまだreturnしていないケースを捕らえるために､ if文の外にreturn文を置く必要があるのです｡

58
00:04:38,040 --> 00:04:40,950
‫そしてここでは､ このキャラクターは死んだのか？

59
00:04:40,950 --> 00:04:46,500
‫まあ､ そうですね､ 基本的にはそうでないと､ 基本的には死んでしまいます｡

60
00:04:46,590 --> 00:04:53,850
‫もしポーンがなければ､ ポーンをコントロールできなければ､ このコントローラーは私たちにとって死んだも同然なのです｡

61
00:04:54,030 --> 00:05:00,360
‫そして､ ポーンは死ぬとAIコントローラーから切り離されることを思い出して､ そうなる可能性があります｡

62
00:05:01,020 --> 00:05:06,630
‫では､ ゲームモードに戻り､ ここで何をしたいのか？

63
00:05:07,110 --> 00:05:16,650
‫基本的にやりたいことは､ シューターAのIのすべてに対してのforループである｡  I..

64
00:05:17,760 --> 00:05:19,380
‫世界では

65
00:05:20,200 --> 00:05:22,450
‫そしてそのforループで

66
00:05:22,570 --> 00:05:23,740
‫私たちは何をしたいのか？

67
00:05:23,770 --> 00:05:25,990
‫私たちは､ 死んでいる姿を見たいのです｡

68
00:05:27,460 --> 00:05:32,380
‫基本的に､ あるいは基本的に死んではいない｡

69
00:05:33,040 --> 00:05:39,390
‫そして､ どれかひとつでも死んでいなければ､ 全部の目をチェックする必要はまったくないことが瞬時にわかるのです｡

70
00:05:39,400 --> 00:05:44,110
‫Aが1つでもあれば｡  I. が生きていれば､ ゲームオーバーにはならない｡

71
00:05:44,110 --> 00:05:49,180
‫これは､ この関数内のコードをこれ以上実行することなく､

72
00:05:49,180 --> 00:05:54,220
‫この関数を終了させるものです｡

73
00:05:54,220 --> 00:06:00,010
‫つまり､ このアーリーリターンの後はすべて､ forループの実行を停止し､ それ以降はすべて実行を停止します｡

74
00:06:00,550 --> 00:06:14,500
‫しかし､ その後､ 我々はそれが早期に戻ることなく､ この完全なループをうまく乗り切ることができれば､ 生きているAは存在しないことを意味すると言うことができます｡

75
00:06:14,500 --> 00:06:14,500
‫I. ということであれば､ このままゲームを終了させなければなりません｡

76
00:06:15,130 --> 00:06:16,060
‫単純なことです｡

77
00:06:16,090 --> 00:06:22,060
‫さて､ ここで注目すべきは､ パズルの1つである「エンドゲーム」です｡

78
00:06:22,060 --> 00:06:25,860
‫プレイヤーコントローラーでゲームが終了してしまったからです｡

79
00:06:25,870 --> 00:06:29,230
‫シュータープレイヤーのコントローラーが､ 現在どのように対処しているかを見てみましょう｡

80
00:06:29,230 --> 00:06:38,560
‫そのCPのところに行くと､ 現在見えているのは､ B is winnerが勝者かどうかは現在全く無視しているということです｡

81
00:06:39,190 --> 00:06:44,140
‫そこで必要なのは､ Bが勝者であるかどうかということです｡

82
00:06:45,000 --> 00:06:48,600
‫そして､ それ以外のことをするのです｡

83
00:06:48,960 --> 00:06:52,090
‫負け画面を表示することになりました｡

84
00:06:52,110 --> 00:06:55,930
‫そこで､ 負け画面を表示する役割を担っているここのラインをカットしてください｡

85
00:06:55,950 --> 00:07:00,210
‫alt文にそれを入れて､ とにかく両方のケースで再起動させます｡

86
00:07:00,690 --> 00:07:02,630
‫だから現状ではBが勝っている｡

87
00:07:02,640 --> 00:07:03,540
‫どうするんだ？

88
00:07:03,540 --> 00:07:12,440
‫さて､ これからウィンドスクリーンを作るわけですが､ これはかなり簡単なことだと思います｡

89
00:07:12,460 --> 00:07:16,410
‫シュータープレイヤーコントローラーのヘッダーファイルへ移動します｡

90
00:07:16,410 --> 00:07:22,440
‫負け画面のクラスを複製して､ ここに勝ち画面のクラスを作ることができます｡

91
00:07:22,860 --> 00:07:24,750
‫また､ 先に進むこともできます｡

92
00:07:24,750 --> 00:07:26,160
‫そして実は､ これはあなたへのミニ・チャレンジでもあるのです｡

93
00:07:26,160 --> 00:07:29,650
‫ウィンドスクリーンができるように設定してくるかもしれませんね｡

94
00:07:29,970 --> 00:07:30,130
‫なるほど｡

95
00:07:30,240 --> 00:07:30,690
‫お帰りなさい｡

96
00:07:30,690 --> 00:07:33,150
‫だから､ それを試してみてほしい｡

97
00:07:33,150 --> 00:07:41,550
‫私たちは､ すべての敗因の代わりにここにウィンドスクリーンを入れて､ 本質的に他のすべてをコピーして行くだけです｡

98
00:07:42,960 --> 00:07:43,800
‫そうそう｡

99
00:07:44,860 --> 00:07:53,650
‫次に､ これをコンパイルして､ エディタでプレイヤー・コントローラ・クラスを探します｡

100
00:07:53,650 --> 00:07:58,540
‫そして､ 空のウィンドスクリーン・クラスがあることがわかるはずです｡ これから行うのは､

101
00:07:58,540 --> 00:08:05,800
‫UIに移動して､ ウィンドスクリーンを呼び出すためにロスト・スクリーンを複製することです｡

102
00:08:05,800 --> 00:08:11,980
‫でも､ 色を緑に変える以外は､ ほとんど同じように使うつもりです｡

103
00:08:12,650 --> 00:08:17,180
‫そして､ あなたが負けるのではなく､ あなたが勝つようにするのです｡

104
00:08:18,030 --> 00:08:21,870
‫リスタートのロジックが事実上同じになるだけですから｡

105
00:08:21,870 --> 00:08:23,400
‫なぜかそこで色がリセットされてしまいました｡

106
00:08:23,400 --> 00:08:25,670
‫もう一度､ 色を緑に設定してくるだけです｡

107
00:08:25,680 --> 00:08:26,460
‫なるほど､ それは素晴らしい｡

108
00:08:26,460 --> 00:08:31,740
‫しかし､ KMLゲームモードには､ まだ未記入の擬似コードの塊が残っています｡

109
00:08:31,740 --> 00:08:34,840
‫そしてそれは､ 勝利を計算するためのあなたの挑戦でもあるからです｡

110
00:08:34,860 --> 00:08:36,480
‫疑似コードを記入する｡

111
00:08:36,600 --> 00:08:40,680
‫そのクラスの下のTから範囲を参考にしてください｡

112
00:08:40,710 --> 00:08:45,390
‫コントローラで作成したnew is dead関数を使用して､ テストしてください｡

113
00:08:45,420 --> 00:08:49,500
‫世界中のAIを倒したときに､ フロントガラスが表示されるかどうかを確認します｡

114
00:08:49,500 --> 00:08:53,670
‫そこで､ 擬似的なコードを画面に表示したままにしておいて､ 見てもらうことにします｡

115
00:08:54,090 --> 00:08:55,020
‫K おかえりなさい｡

116
00:08:55,020 --> 00:08:56,490
‫では､ まずforループから｡

117
00:08:56,610 --> 00:08:57,720
‫だから､ 4をやるんです｡

118
00:08:57,720 --> 00:08:59,100
‫ループオーバーのために何をするか？

119
00:08:59,100 --> 00:09:00,690
‫現時点ではコントローラーではありません｡

120
00:09:00,690 --> 00:09:03,660
‫シューターのAIコントローラーになりそうですね｡

121
00:09:03,660 --> 00:09:05,340
‫だから､ それを含めてハッシュ化する必要があるのです｡

122
00:09:06,210 --> 00:09:09,570
‫シューターになるんです｡

123
00:09:10,360 --> 00:09:12,340
‫Iコントローラh｡

124
00:09:13,050 --> 00:09:19,620
‫そして､ シューターであるAをループさせるということです｡  I. コントローラ､ スター

125
00:09:20,190 --> 00:09:30,120
‫短パンのコントローラーを呼び出すだけで､ シューターAというtアクターレンジをやり直します｡

126
00:09:30,120 --> 00:09:30,120
‫I. のコントローラーを使用しています｡

127
00:09:30,120 --> 00:09:34,140
‫この2つのタイプを一致させてから､ 世界を手に入れる必要があるのです｡

128
00:09:34,230 --> 00:09:36,540
‫だから､ このレベルでやっているんです｡

129
00:09:37,740 --> 00:09:42,480
‫そして､ このforループの本体は､ 死んでいないかどうかを尋ねているところです｡

130
00:09:42,480 --> 00:09:48,120
‫だから､ そうでなければ､ コントローラの矢は死んでしまう｡

131
00:09:49,720 --> 00:09:52,510
‫基本的には､ 私たちが死んでいないことを確認することを言っているのです｡

132
00:09:52,600 --> 00:10:00,180
‫そして､ 死んでいないのであれば､ まだゲームが終わるはずがないということで､ このまま早々に復帰してしまうのです｡

133
00:10:00,190 --> 00:10:06,910
‫そうでなければ､ もし戻らずにforループの穴を通過してしまった場合､ プレイヤーはレベル内のAIをすべて殺してしまったことになるので､

134
00:10:06,910 --> 00:10:10,330
‫ゲームを終了させる必要があります｡

135
00:10:10,480 --> 00:10:13,180
‫だから､ この場合はエンドゲームをすればいいんです｡

136
00:10:13,180 --> 00:10:13,900
‫本当です｡

137
00:10:13,900 --> 00:10:15,310
‫プレーヤーが持っているからです｡

138
00:10:15,310 --> 00:10:20,440
‫そしてそれは､ 周りのプレイヤー・コントローラーやコントローラーのすべてに通知されるはずです｡

139
00:10:20,830 --> 00:10:21,430
‫かっこいい｡

140
00:10:21,430 --> 00:10:24,040
‫では､ それをコンパイルしてきましょう｡

141
00:10:24,040 --> 00:10:27,850
‫まず､ アンリアルに移ってプレイしてみます｡

142
00:10:27,850 --> 00:10:33,940
‫なぜかエディタがこの編集指定色操作中と勘違いしているので､ 一旦終了して再開します｡

143
00:10:33,940 --> 00:10:38,680
‫再起動したので､ これからプレイを打つと､ 殺されそうです｡

144
00:10:38,680 --> 00:10:39,190
‫まず第一に｡

145
00:10:39,190 --> 00:10:40,450
‫はい､ 今でも負けています｡

146
00:10:40,450 --> 00:10:41,140
‫それは素晴らしいことです｡

147
00:10:41,140 --> 00:10:44,020
‫さて､ 殺される前にこいつを殺せるかどうか｡

148
00:10:44,730 --> 00:10:45,270
‫さあ､ 行こう｡

149
00:10:45,270 --> 00:10:46,980
‫ブーム､ ブーム､ ブーム､ ブーム､ ブーム､ ブーム｡

150
00:10:47,250 --> 00:10:48,180
‫負けるのが早いんです｡

151
00:10:48,180 --> 00:10:52,170
‫もう一度､ 銃を探しに行って､ セットしよう｡

152
00:10:52,170 --> 00:10:56,490
‫テスト用に銃のそのダメージを本当に高くしてあります｡

153
00:10:56,490 --> 00:11:00,720
‫今回はダメージを20くらいに戻してきます｡

154
00:11:00,720 --> 00:11:03,240
‫だから､ 速いことには変わりないのですが､ それほどでもないのです｡

155
00:11:03,270 --> 00:11:06,420
‫こいつを何度か叩いて遊んできてください｡

156
00:11:06,420 --> 00:11:12,210
‫そして､ そこで分かったことは､ レベルが再開されたので､ 実際に私が勝ったということです｡

157
00:11:12,210 --> 00:11:15,660
‫だから､ もし私がもう一度この男を殺しに行っても､ 何も起こらないのがわかるでしょう｡

158
00:11:15,660 --> 00:11:19,860
‫メッセージログに､ nullクラスで呼び出されたcreateと書いてあるのですが｡

159
00:11:19,860 --> 00:11:27,360
‫その理由は､ BPシュータープレイヤーのコントローラーをもう一度見てみると､ ウィンドスクリーンが接続されていないのがわかります｡

160
00:11:27,450 --> 00:11:31,350
‫一つ忘れていたので､ コンパイル､ セーブ､ プレイをしてきてください｡

161
00:11:31,350 --> 00:11:37,980
‫そして今､ うまくいけばこいつを殺してNew Doomに行けば私の勝ちで､ 5秒後にリスタートできる｡

162
00:11:37,980 --> 00:11:40,950
‫そして､ 同じことが言えることを示したいのです｡

163
00:11:41,100 --> 00:11:46,290
‫プレイヤーコントローラーを増やしたら､ 両方殺さないといけなくなりそうだ｡

164
00:11:46,290 --> 00:11:50,160
‫では､ こちらのシューターキャラクターを持ってきましょう｡

165
00:11:50,610 --> 00:11:52,950
‫そして､ これが2番目に殺すべき敵になりそうです｡

166
00:11:52,950 --> 00:11:54,420
‫だからこいつを殺せばいい､ ドカン｡

167
00:11:54,750 --> 00:11:56,850
‫そして､ それは勝っていない｡

168
00:11:56,850 --> 00:11:59,310
‫そして､ 2番目の男のところへ行くと､ ドーン｡

169
00:11:59,310 --> 00:12:09,420
‫そして今､ 私はAIをすべて殺したので1つ持っています｡ そのために変数を変更する必要はありませんでした｡

170
00:12:09,420 --> 00:12:09,420
‫I. 毎回ゼロから

171
00:12:09,420 --> 00:12:12,270
‫ですから､ 現在､ 私たちはかなり静かな世界に住んでいることになります｡

172
00:12:12,270 --> 00:12:18,330
‫そこで次回の講義では､ オーディオをどのようにすればいいのか､ 少しづつ見ていきたいと思います｡

173
00:12:18,360 --> 00:12:19,290
‫現地でお会いしましょう｡

