﻿1
00:00:04,080 --> 00:00:05,730
‫こんにちは､ お帰りなさい｡

2
00:00:05,760 --> 00:00:10,380
‫それでは､ マウスを使ってタレットを回転させましょう｡

3
00:00:10,380 --> 00:00:14,790
‫そして､ そのヒット位置は､ 前の動画で行ったトレースヒットから｡

4
00:00:14,880 --> 00:00:22,200
‫だから､ マウスカーソルを動かしていると､ 砲台が回転してマウスカーソルの方向を向くんだ｡

5
00:00:22,320 --> 00:00:28,110
‫また､ ビューポートでクリックしてプレイを開始しても､ マウスカーソルを動かして砲台を回転させたり､

6
00:00:28,110 --> 00:00:31,080
‫方向を設定したりすることができますね｡

7
00:00:31,110 --> 00:00:35,850
‫これによって､ 弾丸を発射する能力があるときに､ 狙いを定めることができるようになるのです｡

8
00:00:35,880 --> 00:00:36,200
‫なるほど｡

9
00:00:36,240 --> 00:00:41,770
‫そのためには､ 砲塔を向けたい方向を見つける必要があります｡

10
00:00:41,790 --> 00:00:46,410
‫そして､ その方向が決まれば､ あとはタレットのメッシュの回転を設定すればいいのです｡

11
00:00:46,500 --> 00:00:53,500
‫さて､ 砲塔の向きを決めるには､ 少しベクトル計算をする必要があります｡

12
00:00:53,520 --> 00:00:59,570
‫探しているのは､ 戦車の砲塔から追跡したヒット位置までのベクトルです｡

13
00:00:59,580 --> 00:01:06,960
‫これで､ 戦車やその構成部品の位置､ 例えば戦車の砲塔の位置などを簡単に取得できるようになりました｡

14
00:01:06,990 --> 00:01:09,600
‫この場所を､ タレット､ ロケーションと呼ぶことにします｡

15
00:01:09,600 --> 00:01:13,440
‫そして､ トレースヘッドの位置を知る方法もわかっています｡

16
00:01:13,470 --> 00:01:15,800
‫これをトレースヒット位置と呼ぶことにする｡

17
00:01:15,810 --> 00:01:20,760
‫ここで気になるのは､ 砲塔の位置からトレースヒット位置までのベクトルです｡

18
00:01:20,760 --> 00:01:23,100
‫このベクトルをターゲットと呼ぶことにする｡

19
00:01:23,130 --> 00:01:27,030
‫さて､ ターゲットに到達するためのベクトル計算は､ 実はとてもシンプルです｡

20
00:01:27,060 --> 00:01:33,120
‫始点から終点までのベクトルを得るには､ 常に終点から始点を引いた値になります｡

21
00:01:33,420 --> 00:01:41,620
‫つまり､ トレース､ 命中位置から砲塔位置のベクトルを引くと､ その結果得られるベクトルはターゲットになります｡

22
00:01:41,640 --> 00:01:49,530
‫さて､ 2つの目標方向ベクトルができたら､ それを回転に変換して､ 戦車の砲塔の回転を設定したいと思います｡

23
00:01:49,530 --> 00:01:53,750
‫そして､ ベクトル型にはrotationという関数が内蔵されている｡

24
00:01:53,760 --> 00:02:02,260
‫つまり､ ターゲットへのベクトルに対してrotationを呼び出すと､ その方向に対応するFローテータが返されることになる｡

25
00:02:02,280 --> 00:02:04,430
‫さて､ ここで気をつけなければならないことがあります｡

26
00:02:04,440 --> 00:02:14,620
‫トレースヒット結果は床に落ちることが多く､ 戦車の砲塔からトレースヒット結果へのベクトルは地面と平行にはなりません｡

27
00:02:14,640 --> 00:02:20,850
‫つまり､ 戦車の砲塔の回転をその方向ベクトルから得られる回転子に設定すると､ 砲塔が地面に向かって下向きになるようなものが得られますが､

28
00:02:20,850 --> 00:02:29,310
‫戦車の砲塔を下向きに回転させたいわけではありません｡

29
00:02:29,310 --> 00:02:31,350
‫まだ前を向いていてほしいのです｡

30
00:02:31,350 --> 00:02:33,780
‫つまり､ これが私たちの望む結果なのです｡

31
00:02:33,810 --> 00:02:39,180
‫つまり､ 戦車の砲塔の回転のうち､ Ya成分だけを変えたいのです｡

32
00:02:39,180 --> 00:02:44,550
‫そうすれば､ 正しい方向を向きつつも､ 地面と平行を保つことができるのです｡

33
00:02:44,550 --> 00:02:51,600
‫今回はヨーのみを変更しましたので､ VSコードに戻り､ 戦車の砲塔を回転させる関数を作成しましょう｡

34
00:02:51,630 --> 00:02:57,210
‫これから戦車の砲塔を回転させますが､ 敵のタワーの砲塔も回転させたいと思います｡

35
00:02:57,210 --> 00:03:08,820
‫タワーはすぐにポン基底から派生して作られるので､ 砲塔の回転関数を作れば､ ポン基底クラスのここに置くことができるということです｡

36
00:03:08,820 --> 00:03:12,930
‫そうすれば､ タンクとタワーの両方がこの機能を継承することになります｡

37
00:03:12,930 --> 00:03:18,480
‫タワーとタンクの両方で使う予定なので､ この機能をプロテクトにすればいいのです｡

38
00:03:18,720 --> 00:03:24,630
‫そこで､ protectedセクションを追加して､ protectedセクションに配置した関数や変数は､ これらの子クラスではアクセスできますが､

39
00:03:24,630 --> 00:03:29,220
‫他のクラスではアクセスできないようにします｡

40
00:03:29,220 --> 00:03:32,580
‫つまり､ プライベート変数とほぼ同じ制約があるわけです｡

41
00:03:32,580 --> 00:03:34,860
‫これで､ この関数はvoidを返すことができるようになりました｡

42
00:03:34,860 --> 00:03:37,710
‫これを回転式タレットと呼ぶことにします｡

43
00:03:38,850 --> 00:03:44,690
‫そして､ 砲塔を回転させるためには､ 見るべき先のようなものが必要になってきますね｡

44
00:03:44,700 --> 00:03:49,620
‫これはfベクトルで､ これをルックアットターゲットと呼ぶことができる｡

45
00:03:49,620 --> 00:04:00,360
‫つまり､ ある関数にワールド内のある種の場所を渡すと､ その場所に向かって砲塔が回転するようになるというアイデアです｡

46
00:04:00,360 --> 00:04:04,680
‫それでは､ タレットを回転させるための関数定義を行ってみましょう｡

47
00:04:04,680 --> 00:04:11,280
‫そこで､ このベースポーンCPのコンストラクタのすぐ下に､ タレットの回転を実装することにします｡

48
00:04:11,280 --> 00:04:16,680
‫そしてもちろん､ ベースとなるポーン・クラス名とスコープ解決演算子がここに必要です｡

49
00:04:16,680 --> 00:04:21,180
‫さて､ タレットを回転させたところで､ これをどのように実装するか考えてみましょう｡

50
00:04:21,180 --> 00:04:30,120
‫まず､ ターゲットベクトルですが､ これはマウスカーソルの下にあるタレット成分からトレースヒット結果までのベクトルです｡

51
00:04:30,120 --> 00:04:38,970
‫つまり､ これはtargetに呼ばれるローカルFベクトルで､ ベクトル計算の結果と等しくなるように設定することができるのです｡

52
00:04:38,970 --> 00:04:43,350
‫出発地から目的地を引いたところになることを忘れないでください｡

53
00:04:43,350 --> 00:04:54,030
‫そして､ 行き先はlook at targetで､ 出発点は戦車の砲塔の位置､ つまり砲塔のメッシュの位置となる予定です｡

54
00:04:54,030 --> 00:04:59,880
‫つまり､ タレットメッシュと言えば､ タレットメッシュの位置が分かるわけです｡

55
00:04:59,880 --> 00:05:07,290
‫さて､ あるコンポーネントのワールドロケーションを取得する方法は､ このget component locationという関数で行います｡

56
00:05:07,290 --> 00:05:09,630
‫使用シーンコンポーネントクラスに属します｡

57
00:05:09,630 --> 00:05:11,460
‫すべてのシーンコンポーネントが持っているわけです｡

58
00:05:11,460 --> 00:05:15,690
‫そこで､ タレットメッシュからコンポーネントの位置の取得を呼び出すことにします｡

59
00:05:16,340 --> 00:05:24,290
‫つまり､ 目標物から砲塔メッシュの位置を引くと､ 砲塔メッシュから見張り目標物までのベクトルが得られます｡

60
00:05:24,320 --> 00:05:30,590
‫さて､ 先ほど述べたように､ Fベクトル回転関数を使って､ ターゲットからEFローテータを得ることができます｡

61
00:05:30,590 --> 00:05:37,100
‫Fローテータを作成し､ これをlook at rotationと呼び､ これをtarget dot

62
00:05:37,100 --> 00:05:40,100
‫rotationに等しく設定します｡

63
00:05:40,280 --> 00:05:41,570
‫それがファンクションコールです｡

64
00:05:41,570 --> 00:05:46,700
‫つまり､ このターゲットへの方向ベクトルに対応する回転子ができたわけです｡

65
00:05:46,700 --> 00:05:49,550
‫しかし､ 私たちはYAにしか関心がないことです｡

66
00:05:49,550 --> 00:05:51,680
‫ピッチや役割を変えたくはないのです｡

67
00:05:51,680 --> 00:05:57,290
‫タレットはz軸の周りに回転させ､ 地面と平行になるようにしたいだけです｡

68
00:05:57,290 --> 00:05:59,420
‫さて､ この方法はいくつもあります｡

69
00:05:59,420 --> 00:06:05,870
‫ひとつは､ 回転､ ピッチを見て､ それをゼロにすることです｡

70
00:06:05,870 --> 00:06:08,180
‫つまり､ ゼロに等しい値を設定します｡

71
00:06:08,210 --> 00:06:14,240
‫また､ ローテーション・ドット・ロールを見て､ これもゼロにすることができます｡

72
00:06:14,240 --> 00:06:21,020
‫さて､ ピッチとロールをゼロにした後､ 欲しい回転は､ コンポーネントだけです｡

73
00:06:21,020 --> 00:06:22,460
‫これもひとつの方法です｡

74
00:06:22,460 --> 00:06:26,450
‫もう一つは､ F ローテーター コンストラクターのオーバーロードの一つを使用することです｡

75
00:06:26,450 --> 00:06:38,300
‫f rotatorとカッコ付きで言って､ 1つ目にゼロ点Fなどの値を渡すと､ ポップアップでその1つ目の入力がピッチであることを教えてくれています｡

76
00:06:38,300 --> 00:06:43,880
‫そして､ 回転をターゲットにするために使用できるヤ｡

77
00:06:44,330 --> 00:06:44,990
‫そうですね｡

78
00:06:44,990 --> 00:06:47,960
‫そして､ 役にはゼロドットFを使うことができます｡

79
00:06:47,960 --> 00:06:59,420
‫これで､ ピッチがゼロ､ ロールがゼロ､ 2つのターゲット回転が返すローテータの成分を持つ新しいFローテータが作成されることになります｡

80
00:06:59,420 --> 00:07:05,300
‫つまり､ これで返される値は､ この3行で行ったのと同じ結果になるのです｡

81
00:07:05,300 --> 00:07:11,990
‫このようにF rotatorコンストラクタを呼び出すことで､ F

82
00:07:11,990 --> 00:07:19,370
‫rotatorから返される回転ベクトルを初期化することができます｡

83
00:07:19,370 --> 00:07:21,380
‫そこで､ この下の行を削除することにします｡

84
00:07:21,380 --> 00:07:23,360
‫そして､ 今度は回転です｡

85
00:07:23,360 --> 00:07:29,000
‫さて､ この関数で最後に行うことは､ タレットマッシュの回転を設定することです｡

86
00:07:29,000 --> 00:07:38,270
‫ここで､ 与えられたコンポーネントの回転を設定するには､ この関数set world rotationを使用します｡

87
00:07:38,270 --> 00:07:44,300
‫ローカルな回転オフセットを追加するのではなく､ セットワード回転を使用する理由は､

88
00:07:44,300 --> 00:07:50,420
‫ワールド空間での回転があるためです 2 ターゲットはワールド空間の方向ベクトルです｡

89
00:07:50,420 --> 00:07:56,750
‫タレットメッシュの位置をワールド空間に取り込み､ ワールド空間のターゲット位置のルックアットを差し引いています｡

90
00:07:56,750 --> 00:07:58,850
‫つまり､ これは世界空間の演出なんですね｡

91
00:07:58,850 --> 00:08:02,450
‫したがって､ ルックアットの回転は､ 世界空間の回転である｡

92
00:08:02,450 --> 00:08:06,140
‫そこで､ タレットメッシュのワールドローテーションを設定することにします｡

93
00:08:06,290 --> 00:08:13,280
‫そこで､ タレットメッシュと言い､ ワールドローテーションを設定し､ ルックアットローテーションを渡すことにします｡

94
00:08:13,280 --> 00:08:19,550
‫これで､ 世界中のどんなターゲットでも､ タレットメッシュを回転させて見ることができる関数ができましたが､

95
00:08:19,550 --> 00:08:22,550
‫メッシュを下向きに回転させることはできません｡

96
00:08:22,550 --> 00:08:28,100
‫ヨーが変わるだけなので､ 戦車の砲塔が回転するような形で回転することになります｡

97
00:08:28,100 --> 00:08:31,100
‫ということで､ 砲台を回転させる機能が出来上がりました｡

98
00:08:31,130 --> 00:08:38,870
‫その砲塔の回転を設定するために､ 戦車クラスのrotate turret関数を呼び出すことに挑戦します｡

99
00:08:38,870 --> 00:08:40,730
‫これは保護された機能です｡

100
00:08:40,730 --> 00:08:43,070
‫だから､ タンククラスはアクセスできるんです｡

101
00:08:43,070 --> 00:08:51,410
‫回転砲塔はFベクトルを取り､ 標的を見るので､ ライントレースから得たFヒット結果にその着弾点を使うつもりだ｡

102
00:08:51,410 --> 00:08:57,170
‫そこで､ コードの中でこの関数を呼び出す正しい場所を見つけるのは､ あなたにお任せすることにします｡

103
00:08:57,410 --> 00:09:00,920
‫そこで､ 動画を一時停止して､ タレットの回転機能を配置します｡

104
00:09:00,920 --> 00:09:02,870
‫戦車クラスで呼び出す｡

105
00:09:06,000 --> 00:09:06,150
‫なるほど｡

106
00:09:06,300 --> 00:09:09,960
‫それでは､ タレットを回転させる関数を用意し､ 呼び出す準備ができました｡

107
00:09:10,140 --> 00:09:18,200
‫タンクアップに入り､ プレイヤーコントローラrefのifチェック内のtick関数を紹介します｡

108
00:09:18,210 --> 00:09:25,860
‫ヒット結果を持っていて､ カーソル下のヒット結果取得が呼ばれた後､ ヒット結果には有効なデータが含まれます｡

109
00:09:25,860 --> 00:09:30,480
‫実は､ そのヒット結果のインパクトポイントを使って､ デバッグ用の球を描いているんです｡

110
00:09:30,510 --> 00:09:35,370
‫これでデバッグ球を描く必要がなくなったので､ 先にそれを削除しておきます｡

111
00:09:35,370 --> 00:09:39,900
‫そして､ その代わりにプロテクトされた関数rotate turretを呼び出すことにします｡

112
00:09:39,900 --> 00:09:45,750
‫そして､ ルックアットターゲットでは､ ヒットリザルト・ドットインパクトポイントでパスすることにしています｡

113
00:09:47,140 --> 00:09:53,320
‫これで､ 毎フレーム､ タレットをヒット結果のインパクトポイントに向かって回転させることになります｡

114
00:09:53,350 --> 00:10:00,130
‫さて､ これをコンパイルする前に､ もうドローデバッグヘルパーは使わないので､ 先に進んでそのヘッダーファイルを削除しておきます｡

115
00:10:00,340 --> 00:10:00,820
‫なるほど｡

116
00:10:00,850 --> 00:10:02,590
‫これで､ コンパイルの準備ができました｡

117
00:10:02,970 --> 00:10:03,360
‫なるほど｡

118
00:10:03,370 --> 00:10:05,050
‫この編集部に戻ってきました｡

119
00:10:05,080 --> 00:10:09,440
‫さっそく再生ボタンを押して確認してみましょう｡

120
00:10:09,460 --> 00:10:11,460
‫これはすごいことです｡

121
00:10:11,470 --> 00:10:12,910
‫まだまだ転がせます｡

122
00:10:12,910 --> 00:10:18,910
‫マウスを動かしても､ マウスカーソルを動かした先で砲台が回転しているんです｡

123
00:10:18,910 --> 00:10:20,350
‫だから､ これはすごいことなんです｡

124
00:10:20,600 --> 00:10:25,750
‫さて､ この話を終える前に､ 2つほど問題点を指摘しておきたいと思います｡

125
00:10:25,750 --> 00:10:28,900
‫これをきれいに磨いて､ 見栄えをよくしてほしいのです｡

126
00:10:28,930 --> 00:10:36,890
‫さて､ 最初の問題は､ マウスカーソルを水槽の中心に近づけてから通過させたときに起こります｡

127
00:10:36,910 --> 00:10:42,670
‫ある時､ そのローテーションが急激に崩れるのがわかると思います｡

128
00:10:42,670 --> 00:10:48,250
‫また､ マウスを無造作に動かしても､ あまり見栄えがよくありません｡

129
00:10:48,250 --> 00:10:49,480
‫折れている｡

130
00:10:49,480 --> 00:10:50,890
‫スムーズな動きができないのです｡

131
00:10:50,890 --> 00:10:52,270
‫それがひとつの課題ですね｡

132
00:10:52,300 --> 00:10:59,890
‫さて､ もうひとつの問題は､ クリックして転がりながら端まで行くと､ マウスカーソルを上に移動させたときに､

133
00:10:59,890 --> 00:11:03,750
‫タレットが別の方向にスナップすることです｡

134
00:11:03,760 --> 00:11:05,730
‫では､ どうなっているのでしょうか？

135
00:11:05,740 --> 00:11:06,910
‫さて､ 確かめてみましょう｡

136
00:11:06,910 --> 00:11:10,240
‫VS Codeに戻り､ デバッグスフィアを取り戻したいと思います｡

137
00:11:10,240 --> 00:11:16,240
‫Tankに戻り､ タレットを回転させる直前のtick関数で､ もう一度､ draw

138
00:11:16,240 --> 00:11:19,240
‫debug sphereを呼び出します｡

139
00:11:19,450 --> 00:11:26,380
‫今､ 私は世界を取得するために渡している 中心は､ 私はヒット結果ドットインパクトポイントを使用します

140
00:11:26,380 --> 00:11:38,440
‫半径は25ドット Fセグメントは12にすることができ､ 色はFカラー赤 永続的な線は偽にすることができ､ 寿命は負の1にすることができます｡

141
00:11:38,440 --> 00:11:40,480
‫だから､ 以前と同じこと｡

142
00:11:40,690 --> 00:11:42,280
‫だから､ このお知らせは保存しておこうと思います｡

143
00:11:42,280 --> 00:11:50,830
‫デバッグヘルパーはデフォルトで含まれているので､ 技術的には必要ないのですが､ ヘッダーファイルを追加し直していません｡

144
00:11:50,830 --> 00:11:56,740
‫エディターでジャンプを保存して､ コーディングのライブキックオフを行い､ 再生ボタンを押すだけです｡

145
00:11:56,740 --> 00:11:58,600
‫これでデバッグスフィアができたわけです｡

146
00:11:58,600 --> 00:12:07,240
‫では､ 世界の端まで行って､ そのマウスカーソルを奈落の底に落ちるところまで動かしてみましょう｡

147
00:12:07,240 --> 00:12:10,330
‫そして､ そこに問題があるのです｡

148
00:12:10,330 --> 00:12:18,730
‫カーソルが上に移動しても､ カーソルの下にヒット結果がないのは､ ヒット結果を得るためのものがそこにないからです｡

149
00:12:18,730 --> 00:12:22,120
‫そのため､ 私たちのインパクトポイントは定義されていません｡

150
00:12:22,120 --> 00:12:25,570
‫そこで必要なのは､ そのライントレースがヒットするものです｡

151
00:12:25,600 --> 00:12:28,810
‫さて､ アンリアル・エンジンには､ 使えるツールがたくさんあります｡

152
00:12:28,810 --> 00:12:35,170
‫ここでドロップダウンをクリックして､ プレースアクターのパネルを開き､ ボリュームと書かれたアイコンを選択して､

153
00:12:35,170 --> 00:12:38,380
‫ブロックボリュームを取得することができます｡

154
00:12:38,380 --> 00:12:39,820
‫ここでブロッキング量です｡

155
00:12:39,820 --> 00:12:41,710
‫そのまま1本引きずります｡

156
00:12:41,740 --> 00:12:44,020
‫だから今､ このブロッキングボリュームがあるんです｡

157
00:12:44,110 --> 00:12:48,190
‫さて､ デフォルトでは､ ブロックボリュームは不可視であるはずです｡

158
00:12:48,190 --> 00:12:54,130
‫詳細パネルでコリジョンまでスクロールすると､ コリジョンプリセットがInvisible

159
00:12:54,130 --> 00:13:00,940
‫Wallになっており､ ほぼすべてをブロックしているように見えます｡

160
00:13:00,940 --> 00:13:08,680
‫ブロックしていないのは可視性チャンネルだけで､ ライントレースはたまたま可視性チャンネルをトレースしています｡

161
00:13:08,680 --> 00:13:13,630
‫私たちの世界で可視性チャネルをブロックしているものはすべて､ 私たちのライントレースにヒットします｡

162
00:13:13,630 --> 00:13:16,540
‫しかし､ この巻はそうではないだろう｡

163
00:13:16,540 --> 00:13:17,860
‫見えないはずのものです｡

164
00:13:17,860 --> 00:13:22,690
‫コリジョンのプリセットで､ ドロップダウンを開き､ カスタムを選択します｡

165
00:13:22,720 --> 00:13:28,300
‫これを変更することで､ コリジョンレスポンスをビジビリティチャンネルに設定することができますね｡

166
00:13:28,300 --> 00:13:29,170
‫ブロックなんです｡

167
00:13:29,170 --> 00:13:34,960
‫つまり､ 私たちのような可視性チャンネルに対してトレースするライントレースは､

168
00:13:34,960 --> 00:13:40,180
‫このボリュームにヒットすることになります｡

169
00:13:40,180 --> 00:13:45,580
‫そこで私ができることは､ このブロッキングボリュームを取り出して､ それをスケールアップすることです｡

170
00:13:45,580 --> 00:13:47,800
‫壁の向こう側にセットする

171
00:13:47,800 --> 00:13:55,900
‫実際､ この壁の境界線に置くことができますし､ 壁と重なるように少し下げます｡

172
00:13:55,900 --> 00:14:03,550
‫そして､ この見えないバリアをY方向にも拡大します｡

173
00:14:03,550 --> 00:14:09,880
‫それを大きくして､ この真ん中に置き､ 少し詰め物をします｡

174
00:14:09,880 --> 00:14:14,050
‫そして､ Z方向にもスケールアップします｡

175
00:14:14,050 --> 00:14:18,460
‫これで､ ライントレースもうまくいくはずです｡

176
00:14:18,460 --> 00:14:20,080
‫では､ その理論を検証してみましょう｡

177
00:14:20,110 --> 00:14:23,170
‫ビューポートでクリックし､ 壁際まで行ってみましょう｡

178
00:14:23,170 --> 00:14:34,240
‫そして確かに､ ライントレースでブロックボリュームに当たっていますし､ タレットが不定な場所を見るために折れるという問題もありません｡

179
00:14:34,240 --> 00:14:40,810
‫その衝撃点のベクトルがすべてゼロなので､ 世界の原点を向いているのでしょう｡

180
00:14:40,810 --> 00:14:43,660
‫今度はこの壁に近づいても､ 同じ問題が発生します｡

181
00:14:43,660 --> 00:14:46,270
‫だから､ このブロッキングボリュームが必要なんです｡

182
00:14:46,600 --> 00:14:48,950
‫私たちのレベルの外周のすべて｡

183
00:14:48,970 --> 00:14:50,590
‫さて､ それはかなり簡単なことです｡

184
00:14:50,590 --> 00:14:54,820
‫このブロッキングボリュームを複製すればいいだけなんです｡

185
00:14:54,820 --> 00:14:59,290
‫これで､ パースビューからトップオルソグラフィックビューに変更することができました｡

186
00:14:59,290 --> 00:15:06,070
‫そこで､ topを選択し､ マウスのホイールでスクロールして､ altを押したままこの壁を複製し､

187
00:15:06,070 --> 00:15:11,620
‫1つをここに置いて､ Eを押して回転モードにすることができます｡

188
00:15:11,620 --> 00:15:14,740
‫そこで､ altを押しながら90度回転させます｡

189
00:15:14,740 --> 00:15:21,010
‫コピーして､ ダブルユーで翻訳モードにし､ それをこちら側に移動して､

190
00:15:21,010 --> 00:15:26,920
‫Altを押したままコピーをこちら側にドラッグします｡

191
00:15:26,920 --> 00:15:28,720
‫これで4つの壁ができたわけです｡

192
00:15:28,720 --> 00:15:34,990
‫トップビューからパースに戻り､ 再生ボタンを押すと､ どの壁に近づいても､

193
00:15:34,990 --> 00:15:40,240
‫どの壁に覆われていても大丈夫になりました｡

194
00:15:40,240 --> 00:15:42,340
‫これで問題のひとつが解決しましたね｡

195
00:15:42,340 --> 00:15:43,720
‫しかし､ このもう1つはどうでしょう？

196
00:15:43,720 --> 00:15:49,360
‫水槽の近くでマウスを動かしても､ このような散発的な挙動が見られます｡

197
00:15:49,360 --> 00:15:51,880
‫だから､ そこも大事にしたいですね｡

198
00:15:51,880 --> 00:15:56,770
‫さて､ これを解決する方法は､ 回転を補間することです｡

199
00:15:56,770 --> 00:16:02,650
‫そこで､ この回転値を直接設定する代わりに､ 補間関数を使用することで､

200
00:16:02,650 --> 00:16:08,740
‫基本的に回転を滑らかに指定した目標に向かって移動させることができます｡

201
00:16:08,740 --> 00:16:10,270
‫では､ その様子をご覧ください｡

202
00:16:10,270 --> 00:16:15,970
‫この補間をタレットの回転関数に組み込み､ ベースポーンに戻りタレットを回転させ､

203
00:16:15,970 --> 00:16:22,750
‫タレットの回転を見るために世界の回転を設定する代わりに､ 補間関数が返す値と同じに設定できるようにしたいのですが､

204
00:16:22,750 --> 00:16:28,240
‫いかがでしょうか？

205
00:16:28,240 --> 00:16:38,590
‫そこで､ 回転を削除して､ 代わりにR inter twoというF math library上の関数を呼び出すことにします｡

206
00:16:39,100 --> 00:16:44,530
‫さて､ 私たちの in two はローテーターの補間を扱うように設計されています｡

207
00:16:44,530 --> 00:16:49,720
‫さて､ その最初の入力パラメータはcurrentと呼ばれるconst F rotator referenceである｡

208
00:16:49,720 --> 00:16:53,650
‫それが､ 変えようとしているものの現在値です｡

209
00:16:53,650 --> 00:16:59,560
‫タレットの回転を変更したいのですが､ タレットメッシュからそれを得ることができます｡

210
00:16:59,560 --> 00:17:05,920
‫ここではタレットメッシュとし､ 使用する関数はコンポーネントの回転を取得するものとします｡

211
00:17:05,920 --> 00:17:10,420
‫つまり､ コンポーネントの位置を取得するのと同じように､ 回転を取得するのです｡

212
00:17:10,420 --> 00:17:14,200
‫さて､ 次の入力はTargetと呼ばれるFローテータです｡

213
00:17:14,200 --> 00:17:15,310
‫それが価値です｡

214
00:17:15,310 --> 00:17:21,430
‫この砲塔のメッシュの回転を解釈して､ スムーズに接近できるようにしたいのです｡

215
00:17:21,430 --> 00:17:23,890
‫それが､ ローテーションの見方です｡

216
00:17:23,890 --> 00:17:26,620
‫だから､ ローテーションを見ろということになるんです｡

217
00:17:26,620 --> 00:17:28,630
‫次の入力はデルタ時間です｡

218
00:17:28,630 --> 00:17:30,640
‫だから､ 私たちはデルタタイムの重要性を知っているのです｡

219
00:17:30,640 --> 00:17:37,030
‫物を動かしたり､ 回転させたりする場合､ その動きはフレームレートに依存しないようにしたいのです｡

220
00:17:37,030 --> 00:17:39,700
‫その分､ デルタタイムを確保できるわけです｡

221
00:17:39,700 --> 00:17:46,210
‫単純にゲームプレイのスタティックを入れればいいし､ 記憶力のいい人なら､ includeがkismet slash gameplay

222
00:17:46,210 --> 00:17:49,150
‫staticsだと覚えているはずです｡

223
00:17:49,150 --> 00:18:01,150
‫ここでゲームプレイのスタティック関数にアクセスし､ ワールドデルタ秒を取得します｡ このとき､ ワールドコンテキストオブジェクトが必要になることを忘れないでください｡

224
00:18:01,150 --> 00:18:04,030
‫だから､ これをそっちに回すんです｡

225
00:18:04,030 --> 00:18:06,340
‫そして最後に､ 社内スピードが必要です｡

226
00:18:06,340 --> 00:18:12,280
‫内部速度の値が大きいほど､ 目標に向かって速く補間することになる｡

227
00:18:12,280 --> 00:18:18,550
‫この値を例えば5Fに設定すると､ かなりゆっくり補間されることになります｡

228
00:18:18,580 --> 00:18:20,470
‫では､ この様子をご覧ください｡

229
00:18:20,470 --> 00:18:25,030
‫これがすべて1行にまとまっていて､ 画面からはみ出るほどです｡

230
00:18:25,030 --> 00:18:32,440
‫そこで､ 世界の回転を設定するための入力を､ このように独立した行に配置します｡

231
00:18:32,440 --> 00:18:34,060
‫だから､ そのまんま｡

232
00:18:34,060 --> 00:18:39,820
‫そして､ インタプリタが､ これら4つの入力パラメータを持ち､ 画面外を走っています｡

233
00:18:39,820 --> 00:18:43,270
‫そこで､ それぞれを独立した行に設定することにします｡

234
00:18:43,270 --> 00:18:49,420
‫そうすれば､ あのように画面をスクロールすることなく､ すべての入力を見ることができるのです｡

235
00:18:49,420 --> 00:18:49,840
‫わかりました｡

236
00:18:49,840 --> 00:18:54,220
‫このまま保存して､ ライブコーディングを開始するつもりです｡

237
00:18:54,220 --> 00:19:01,480
‫再生ボタンを押してマウスを動かすと､ 回転にしばらく時間がかかることがわかります｡

238
00:19:01,480 --> 00:19:06,430
‫それは､ その目標回転に向かって滑らかに補間しているからです｡

239
00:19:06,430 --> 00:19:07,780
‫さて､ これは素晴らしいことです｡

240
00:19:07,780 --> 00:19:09,340
‫それこそ､ 私が欲しかったものです｡

241
00:19:09,340 --> 00:19:14,950
‫どうマウスを動かしても､ あのキビキビしたジャキジャキとした散発的な動きは出せないのです｡

242
00:19:15,040 --> 00:19:20,170
‫今､ 5というのはものすごく遅いインターネット速度ですが､ それを変えることができるんです｡

243
00:19:20,170 --> 00:19:21,820
‫もう少し速くできるはずです｡

244
00:19:21,820 --> 00:19:30,040
‫これを25に設定して､ どう見えるかを見て､ 自分のゲームに合った値を決めてもらうことにします｡

245
00:19:30,040 --> 00:19:34,450
‫だから､ もう1回､ ライブコーディングを蹴って､ 再生ボタンを押してください｡

246
00:19:34,510 --> 00:19:39,010
‫これでかなり高速な補間ができるようになったのですが､ スナップが効きません｡

247
00:19:39,010 --> 00:19:42,910
‫それでも早いんですが､ 瞬発力がないんです｡

248
00:19:42,910 --> 00:19:46,360
‫だから､ こういうことをやっていない限り､ まあ､ それはないでしょう｡

249
00:19:46,540 --> 00:19:47,860
‫クレイジーな行動

250
00:19:47,860 --> 00:19:53,500
‫もちろん､ もっとゆっくり回転させたい場合は､ その方法はもうお分かりでしょうし､ デバッグ球の描画も終わりましたので､

251
00:19:53,500 --> 00:19:56,220
‫先にそれを削除しておきますね｡

252
00:19:56,230 --> 00:19:56,650
‫なるほど｡

253
00:19:56,650 --> 00:20:05,800
‫要約すると､ タレットの回転を設定し､ ワールド内の点に対応するFベクトルであるルックアットターゲットを渡しています｡

254
00:20:05,800 --> 00:20:08,080
‫今はトレースヒット結果だけを使っています｡

255
00:20:08,110 --> 00:20:15,880
‫さて､ この関数をベースとなるポンクラスに入れ､ protectedにしたことで､ タンククラスの関数を継承することができました｡

256
00:20:15,880 --> 00:20:21,190
‫そして､ ベースとなるタワークラスを作る準備ができたら -- そのタワークラスはこのrotate

257
00:20:21,190 --> 00:20:24,610
‫turret関数を継承して､ 再利用できるようになります｡

258
00:20:24,610 --> 00:20:26,050
‫あとは合格するだけです｡

259
00:20:26,050 --> 00:20:32,380
‫ターゲットの新しい姿として､ ベースから派生したタワークラスの作成に取り組む--というのが､ これからの講義です｡

260
00:20:32,380 --> 00:20:33,250
‫また､ お会いしましょう｡

