﻿1
00:00:04,380 --> 00:00:06,150
‫こんにちは､ お帰りなさい｡

2
00:00:06,240 --> 00:00:12,920
‫これで...は動きますが､ 砲塔と呼んでいる上部のパーツは回転させません｡

3
00:00:12,930 --> 00:00:16,290
‫だから､ マウスを使ってできるようにしたいんです｡

4
00:00:16,320 --> 00:00:18,800
‫さて､ ここで何が起こっているのか見てみましょう｡

5
00:00:18,810 --> 00:00:23,300
‫ワールド内でマウスカーソルを動かしていると､ このような赤い球体が出てきます｡

6
00:00:23,310 --> 00:00:27,060
‫これは､ 3D空間に描いているデバッグ用の球体です｡

7
00:00:27,300 --> 00:00:33,600
‫ここで､ 私が壁に向かって移動すると､ その球体は壁の表面に対して移動することに気づきます｡

8
00:00:33,600 --> 00:00:43,620
‫だから､ マウスカーソルが動いている場所には､ カーソルの位置に基づいてヒットしているオブジェクトに対応する恐怖を感じることができるんだ｡

9
00:00:43,620 --> 00:00:51,200
‫これは､ タレットを回転させる場所を空間内に設定するのに便利です｡

10
00:00:51,210 --> 00:00:59,250
‫さて､ これを行うには､ コントローラ上で必要な関数がいくつかあるので､ コントローラ上でそれらの関数にアクセスする必要があります｡

11
00:00:59,250 --> 00:01:07,080
‫このビデオでは､ その設定と､ キャスティングと呼ばれる概念をどのように使用するかについて説明します｡

12
00:01:07,080 --> 00:01:14,820
‫さて､ なぜコントローラが必要かというと､ コントローラにはカーソルの下にヒット結果を取得するための関数があるからです｡

13
00:01:14,820 --> 00:01:16,860
‫今度はマウスカーソルの話です｡

14
00:01:16,860 --> 00:01:20,310
‫例えば､ これが画面､ これがマウスカーソルです｡

15
00:01:20,310 --> 00:01:25,530
‫そして､ カーソルの先端にある点が､ 画面上のある場所に対応しています｡

16
00:01:25,530 --> 00:01:31,740
‫カーソルを移動させると､ 戦車の砲塔部分､ つまりメッシュの上部が回転し､

17
00:01:31,740 --> 00:01:37,290
‫カーソルの方向を向くようにすることが目的です｡

18
00:01:37,440 --> 00:01:47,190
‫カーソルを移動させると､ そのカーソルに対応する位置を取得するための関数がコントローラに用意されています｡

19
00:01:47,190 --> 00:01:52,830
‫カメラからカーソルに向かって直線を引き､ ワールド内の何らかのオブジェクトにぶつければ､

20
00:01:52,830 --> 00:01:59,700
‫その位置を取得し､ その位置を使って戦車の砲塔の回転を設定することができます｡

21
00:01:59,730 --> 00:02:00,960
‫どういうことか､ お見せしましょう｡

22
00:02:00,960 --> 00:02:06,420
‫さて､ このカーソルに対応するヒット位置を取得するために､ コントローラを使用する必要があります｡

23
00:02:06,420 --> 00:02:09,480
‫さて､ ここでちょっとだけコントローラーの話を｡

24
00:02:09,780 --> 00:02:11,880
‫私たちのポーンがあるとしましょう｡

25
00:02:11,880 --> 00:02:13,950
‫ポーンはコントローラーを持つことになります｡

26
00:02:14,130 --> 00:02:18,210
‫これはポーンに関連する目に見えないオブジェクトです｡

27
00:02:18,210 --> 00:02:27,720
‫さて､ ポーンですが､ コントローラはタイプAのプレイヤーコントローラを持ち､ ゲーム開始時にはコントローラがポーンを所持することになります｡

28
00:02:27,750 --> 00:02:32,790
‫そのため､ ポーンタンクが持っているカメラの視点で見ることができるのです｡

29
00:02:32,790 --> 00:02:34,890
‫これで､ このコントローラにアクセスできるようになりました｡

30
00:02:34,920 --> 00:02:38,970
‫戦車クラスはGet Controllerという関数を継承しています｡

31
00:02:38,970 --> 00:02:41,100
‫これは -- クラスから継承されています｡

32
00:02:41,100 --> 00:02:51,270
‫そこで､ このコントローラを取得し､ 変数に格納して､ カーソル下のヒット結果を得るために必要な関数にアクセスできるようにしたいのです｡

33
00:02:51,270 --> 00:02:53,010
‫だから､ そのための準備をしよう｡

34
00:02:53,010 --> 00:02:58,650
‫今､ 私はこのタンククラスにいて､ コントローラにアクセスする必要があるのはplayを始めるところです｡

35
00:02:58,680 --> 00:03:05,190
‫もし､ コンストラクタで実行すると､ 早すぎて､ まだ有効なコントローラができていない可能性があります｡

36
00:03:05,190 --> 00:03:08,910
‫そこで､ このタンククラスでbegin play関数が必要になります｡

37
00:03:08,910 --> 00:03:15,090
‫このクラスは pong クラスのベースになっていますが､ 今のところ pong クラスのベースでは begin play は使っていません｡

38
00:03:15,270 --> 00:03:18,450
‫そこで､ 私がやりたいのは､ それをタンククラスに移すことです｡

39
00:03:18,450 --> 00:03:25,500
‫そこで､ ここのコメントとプロテクトされた部分を含めてビギンプレイを強調し､ シンプルにカットすることにしました｡

40
00:03:25,500 --> 00:03:28,710
‫そして､ タンクステージに戻り､ 貼り付けます｡

41
00:03:28,710 --> 00:03:33,960
‫プライベートセクションのすぐ上に､ このプロテクトセクションを追加し､ 中でプレイを開始するようにしましょう｡

42
00:03:33,960 --> 00:03:36,270
‫これで､ ベースポーンからBegin Playを取り除きました｡

43
00:03:36,840 --> 00:03:41,430
‫もうここにはありませんが､ base pond cpp からも削除する必要があります｡

44
00:03:41,460 --> 00:03:42,240
‫これです｡

45
00:03:42,240 --> 00:03:51,330
‫ここで削除して､ タンクHで宣言したことになりますが､ タンクCPPでも定義する必要があります｡

46
00:03:51,360 --> 00:03:55,830
‫そこで､ プレーヤー入力コンポーネントのセットアップの直下に関数を定義することにします｡

47
00:03:55,830 --> 00:04:00,660
‫つまり､ 入力パラメータがないボイドビギンプレイになるわけです｡

48
00:04:00,870 --> 00:04:06,840
‫関数本体があり､ 関数名を固定するタンクプリも必要です｡

49
00:04:06,840 --> 00:04:09,930
‫これで､ スーパービッグ・イン・プレーを呼び出すことが重要であることがわかった｡

50
00:04:09,930 --> 00:04:17,010
‫そうすれば､ begin play関数や親クラスにある機能はすべて呼び出されたままになります｡

51
00:04:17,340 --> 00:04:18,960
‫そこで､ プレイを開始します｡

52
00:04:18,990 --> 00:04:22,560
‫ここでコントローラを取得し､ 変数に格納することができます｡

53
00:04:22,560 --> 00:04:25,920
‫では､ Hタンクに戻り､ 変数を作ってみましょう｡

54
00:04:25,920 --> 00:04:30,750
‫これはプライベートセクションの一番下に貼り付けて､

55
00:04:30,750 --> 00:04:38,460
‫プレーヤーコントローラーのポインタータイプにします｡

56
00:04:38,460 --> 00:04:40,920
‫これがプレーヤーコントローラーへの参照となります｡

57
00:04:40,950 --> 00:04:43,590
‫今は､ C++のリファレンスの話ではない｡

58
00:04:43,590 --> 00:04:48,750
‫これはまだ単なるポインターですが､ これをプレーヤーのコントローラーを参照するために使用します｡

59
00:04:48,750 --> 00:04:57,600
‫これで､ タイプA player controllerのref変数ができ､ このポインタにコントローラを格納する準備ができました｡

60
00:04:57,600 --> 00:05:02,730
‫では､ ここでTank Dot CPに戻ってプレイを開始し､ このようなことを試みてみましょう｡

61
00:05:02,730 --> 00:05:03,330
‫だから

62
00:05:03,400 --> 00:05:12,100
‫これから行うのは､ プレーヤー､ コントローラー､ レフイコールと言い､ コントローラーの取得を呼び出そうとするものです｡

63
00:05:12,880 --> 00:05:17,440
‫さて､ コントローラの取得ですが､ 先ほど述べたように -- クラスにあります｡

64
00:05:17,470 --> 00:05:24,070
‫右クリックで定義に進み､ この関数がAコントローラを返すことに注目しましょう｡

65
00:05:24,100 --> 00:05:29,020
‫今､ 私たちの変数のタイプはA player controllerであり､ controllerではありません｡

66
00:05:29,020 --> 00:05:40,270
‫つまり､ コントローラポインタ型のget controllerの戻り値を､ Aプレーヤーのコントローラポインタに格納しようとしているのです｡

67
00:05:40,300 --> 00:05:42,330
‫ここで､ 赤い四角い線が見えることに注意してください｡

68
00:05:42,340 --> 00:05:43,940
‫型の値と書いてある｡

69
00:05:43,960 --> 00:05:48,080
‫コントローラポインタは､ タイプのエンティティに割り当てることはできません｡

70
00:05:48,100 --> 00:05:49,630
‫プレイヤーコントローラー｡

71
00:05:49,660 --> 00:05:51,210
‫エラーが発生しました｡

72
00:05:51,220 --> 00:05:55,390
‫ここでは､ コントローラのドキュメントを見てみましょう｡

73
00:05:55,420 --> 00:05:56,400
‫見てみてください｡

74
00:05:56,410 --> 00:05:58,030
‫これがコントローラーです｡

75
00:05:58,030 --> 00:06:00,460
‫そして､ 継承､ 階層と書かれています｡

76
00:06:00,460 --> 00:06:05,690
‫そして､ コントローラーの下には､ コントローラーとプレイヤーコントローラーが見えます｡

77
00:06:05,710 --> 00:06:10,210
‫つまり､ プレイヤーコントローラはコントローラの子クラスということになります｡

78
00:06:10,240 --> 00:06:14,500
‫さて､ C++では､ 型のポインタを持つことはできない｡

79
00:06:14,530 --> 00:06:20,200
‫プレーヤーコントローラーは､ Aコントローラーのアドレスの値を格納します｡

80
00:06:20,530 --> 00:06:22,600
‫コントローラは親タイプです｡

81
00:06:22,780 --> 00:06:25,450
‫プレーヤーコントローラーは子型です｡

82
00:06:25,450 --> 00:06:30,960
‫親型のオブジェクトを子型のポインタに格納することはできません｡

83
00:06:30,970 --> 00:06:32,680
‫では､ どうすればいいのか｡

84
00:06:32,680 --> 00:06:34,000
‫そこで､ 私たちの問題です｡

85
00:06:34,000 --> 00:06:38,630
‫Get controller関数は､ Aコントローラのアドレスを返します｡

86
00:06:38,650 --> 00:06:45,410
‫さて､ これはAコントローラポインタに格納できるものですが､ Aプレイヤーコントローラポインタに格納することはできません｡

87
00:06:45,430 --> 00:06:52,000
‫しかし､ 面白いことに､ get controllerで返されるオブジェクトは､ 実際にはプレイヤーコントローラなのです｡

88
00:06:52,000 --> 00:06:58,630
‫つまり､ このアドレスはAコントローラポインタの形で持っていて､ それがプレーヤーコントローラを格納していることは分かっているのですが､

89
00:06:58,630 --> 00:07:06,210
‫Aコントローラの形で持っていると､ 必要な関数がプレーヤーコントローラ上に存在するため､ アクセスできないのです｡

90
00:07:06,220 --> 00:07:08,810
‫この関数は､ カーソル下のヒット結果を取得するために呼び出されます｡

91
00:07:08,830 --> 00:07:15,250
‫ここで､ タイプAのコントローラポインタの値を持っていて､ プレイヤーコントローラ上に存在するその関数を取得しようとすると､

92
00:07:15,250 --> 00:07:18,430
‫失敗することになります｡

93
00:07:18,460 --> 00:07:20,020
‫コンパイルエラーが出ます｡

94
00:07:20,020 --> 00:07:25,960
‫つまり､ オブジェクト自体がプレイヤーコントローラであることが分かっているので､ Aコントローラポインタに格納されているだけなのです｡

95
00:07:25,960 --> 00:07:27,610
‫この問題をどう回避するか｡

96
00:07:27,610 --> 00:07:29,980
‫答えは､ キャストしなければならない｡

97
00:07:30,010 --> 00:07:36,100
‫コントローラが親クラスで､ プレイヤーコントローラが子クラスであることは分かっています｡

98
00:07:36,100 --> 00:07:41,320
‫そして､ AプレーヤーのコントローラーポインターにAコントローラーを格納させることができないことも分かっています｡

99
00:07:41,320 --> 00:07:47,530
‫逆に､ プレイヤーコントローラーのオブジェクトであるAコントローラーのポインターストアを持つことができることも分かっています｡

100
00:07:47,620 --> 00:07:55,120
‫実際､ get controllerを呼び出すと､ Aプレーヤーのコントローラを指すAコントローラポインタが返されます｡

101
00:07:55,120 --> 00:08:05,920
‫そこで､ A型コントローラポインタの値があれば､ キャストと呼ばれる特殊な関数を使って､ ポインタの型をA型プレイヤーコントローラポインタに変換することができるのです｡

102
00:08:05,920 --> 00:08:15,640
‫つまり､ キャストは､ オブジェクト自体がキャスト先の型である限り､ あるポインタの型を別のポインタの型に変更するのです｡

103
00:08:15,670 --> 00:08:23,140
‫ここで､ 無効な型にキャストしようとすると､ 例えば､ Aコントローラポインタがプレイヤーコントローラオブジェクトを指しているとします｡

104
00:08:23,140 --> 00:08:30,820
‫例えば文字にキャストしようとすると､ キャスト関数はnullを返すので､ キャストに失敗したと言うことになります｡

105
00:08:30,820 --> 00:08:33,160
‫つまり､ キャスト機能は次のようなものだ｡

106
00:08:33,190 --> 00:08:36,790
‫これは､ デフォルトのサブオブジェクトを作成するのと同じように､ テンプレートです｡

107
00:08:36,790 --> 00:08:44,230
‫このテンプレート関数は､ 選択された型に適応し､ この関数では､ 渡す型がキャストする型でもあります｡

108
00:08:44,230 --> 00:08:45,400
‫だから､ その型を渡すのです｡

109
00:08:45,400 --> 00:08:52,570
‫角括弧の中に2つキャストしたいので､ キャストしたいポインタを括弧の中に渡します｡

110
00:08:52,570 --> 00:08:53,710
‫以下はその一例です｡

111
00:08:53,710 --> 00:08:59,410
‫例えば､ プレイヤーコントローラとA型コントローラ型のポインタにキャストしたいとします｡

112
00:08:59,410 --> 00:09:04,240
‫ポインタを括弧で囲み､ キャストする型を角括弧で囲んで渡します｡

113
00:09:04,240 --> 00:09:08,590
‫そして､ 返されるのは､ Aプレイヤー・コントローラー・ポインター型の値です｡

114
00:09:08,590 --> 00:09:18,550
‫この関数呼び出しでは､ 角括弧の中に型を渡し､ 括弧の中にはコントローラを取得した際に返されるコントローラポインタの値を渡します｡

115
00:09:18,550 --> 00:09:22,630
‫そこで､ getコントローラから返されるこの値をキャストする必要があります｡

116
00:09:22,630 --> 00:09:24,250
‫それがあなたのチャレンジになります｡

117
00:09:24,250 --> 00:09:33,550
‫そこでBegin Playでは､ get controller関数を使って､ その値をcast関数に渡し､ プレイヤーコントローラにキャストします｡

118
00:09:33,550 --> 00:09:40,120
‫そして､ その結果をプレイヤーコントローラ参照ポインタ（タイプAプレイヤーコントローラポインタ）に格納することができます｡

119
00:09:40,120 --> 00:09:42,580
‫映像を一時停止して､ キャストを実行する｡

120
00:09:45,530 --> 00:09:45,860
‫なるほど｡

121
00:09:45,860 --> 00:09:49,570
‫これでほぼ全ての作業が完了しましたので､ あとはキャスティングするだけです｡

122
00:09:49,580 --> 00:09:56,000
‫そこで､ これから行うのは､ 括弧だけでなく､ 山括弧もあるキャスト関数を呼び出すことです｡

123
00:09:56,000 --> 00:09:59,990
‫そして､ 括弧の中に入っているのが､ キャストしたい値です｡

124
00:09:59,990 --> 00:10:05,060
‫ここで, get controllerはType Aのコントローラへのポインタを返します．

125
00:10:05,060 --> 00:10:07,850
‫それをここの括弧の中に移動させるんです｡

126
00:10:07,850 --> 00:10:12,110
‫そして､ 今回キャストするタイプは､ プレーヤーコントローラーです｡

127
00:10:14,050 --> 00:10:17,620
‫ですから､ ここでも会計監査人から返された値を採用しています｡

128
00:10:17,620 --> 00:10:21,160
‫comptroller ポインタまたはアドレスを返す｡

129
00:10:21,160 --> 00:10:25,000
‫そして､ castを使ってAプレイヤーのコントローラーにキャストしています｡

130
00:10:25,000 --> 00:10:32,320
‫gate controllerが返すオブジェクトは､ A controller pointerに格納されたA player controllerオブジェクトであることが分かっています｡

131
00:10:32,320 --> 00:10:38,500
‫つまり､ これをキャストした後に返されるのは､ タイプAのプレイヤー・コントローラーのポインターです｡

132
00:10:38,500 --> 00:10:41,410
‫そこで､ プレイヤーコントローラーのrefに格納することにしました｡

133
00:10:41,410 --> 00:10:50,830
‫Aプレイヤーのコントローラポインタという形でコントローラにアクセスできるようになったので､ カーソル下のトレースヒット結果を取得するために必要な関数にアクセスできるようになりました｡

134
00:10:50,830 --> 00:10:55,570
‫つまり､ 要約すると､ get controllerを使って､ コントローラにアクセスすることができたということです｡

135
00:10:55,930 --> 00:11:03,670
‫また､ A型コントローラポインタからA型プレイヤーコントローラポインタへのキャストは､ キャスト関数を使用しています｡

136
00:11:03,670 --> 00:11:11,290
‫これで､ A player controller クラスに存在するカーソルの下のヒット結果を取得する関数にアクセスできるようになりました｡

137
00:11:11,290 --> 00:11:14,500
‫というわけで､ 次回の動画からこの機能を使っていきます｡

138
00:11:14,860 --> 00:11:15,850
‫また､ お会いしましょう｡

