﻿1
00:00:04,470 --> 00:00:08,280
‫つまり､ ベースとなるクラスにはいくつかのコンポーネントが必要だということがわかります｡

2
00:00:08,280 --> 00:00:12,570
‫戦車の下部と砲塔のベースメッシュが必要なことは分かっています｡

3
00:00:12,600 --> 00:00:15,270
‫また､ 上部のタレットメッシュも必要です｡

4
00:00:15,300 --> 00:00:19,500
‫衝突を処理するカプセルが必要で､ 投射物のスポーンポイントが必要です｡

5
00:00:19,500 --> 00:00:21,270
‫それはシーンの構成要素になりそうですね｡

6
00:00:21,300 --> 00:00:28,320
‫さて､ これらの項目をベース・ポッド・クラスに追加すると､ このクラスに基づいて作成するものはすべて､ これらの項目を継承することになります｡

7
00:00:28,320 --> 00:00:35,550
‫だから､ 戦車をベースにして......それから塔もベースにして......｡

8
00:00:35,700 --> 00:00:39,620
‫そして､ ベースポッドをベースにしているので､ これらのコンポーネントを継承しています｡

9
00:00:39,630 --> 00:00:46,800
‫戦車は､ 独自のベースメッシュ､ 独自のタレットメッシュ､ 独自のカプセル､ 独自の弾丸のスポーンポイントを持つことができます｡

10
00:00:46,800 --> 00:00:53,370
‫そして同様に､ タワーには独自のベースメッシュのタレットメッシュカプセル部品とプロジェクタイルスポーンポイントも用意されます｡

11
00:00:53,370 --> 00:00:58,560
‫そして､ それぞれに異なるメッシュを割り当てて､ 異なる見た目にする方法もすぐにわかるでしょう｡

12
00:00:58,560 --> 00:01:00,750
‫だから､ いくつかの部品が必要なことは分かっています｡

13
00:01:00,750 --> 00:01:05,490
‫さて､ いよいよベースとなる -- クラスに実際にコンポーネントを追加してみましょう｡

14
00:01:05,910 --> 00:01:12,240
‫さて､ デフォルトでは､ すでに公開セクション､ 保護セクション､ そして2番目の公開セクションがここにあります｡

15
00:01:12,570 --> 00:01:17,520
‫複数の公開部を設ける理由は様々ですが､ それについては後述します｡

16
00:01:17,520 --> 00:01:20,880
‫しかし､ 今回のコンポーネントでは､ プライベートセクションを作成することにします｡

17
00:01:22,070 --> 00:01:31,790
‫以前学んだように､ メンバー変数はプライベート変数にするのがよいでしょう｡ そうすれば､ その変数を所有するクラスの中からのみアクセスできるようになります｡

18
00:01:31,790 --> 00:01:33,410
‫そこで､ いくつかの部品が必要です｡

19
00:01:33,680 --> 00:01:36,190
‫まず加えるのは､ カプセルです｡

20
00:01:36,200 --> 00:01:40,760
‫そこで､ you capsule componentというタイプの変数を作ってみましょう｡

21
00:01:42,160 --> 00:01:44,030
‫さて､ これがポインターになります｡

22
00:01:44,070 --> 00:01:50,340
‫整数や浮動小数点などの基本型でない限り､ 変数の大部分にはポインターを使用するつもりです｡

23
00:01:50,350 --> 00:01:56,860
‫ご存知のように､ それはポインタが軽量で､ 単なるアドレスであり､ より効率的な作業を可能にするためです｡

24
00:01:56,950 --> 00:02:04,030
‫そこで､ このUカプセルコンポーネントのポインタを､ カプセルコンポーネントの略称であるカプセルコンプと呼ぶことにします｡

25
00:02:04,030 --> 00:02:14,020
‫カプセルコンポーネントのすぐ上に､ アンリアルエンジン特有のマクロを追加します｡

26
00:02:14,020 --> 00:02:20,980
‫この変数をアンリアル・エンジンに認識させ､ アンリアル・エンジンに参加できるようにする方法が､ Youプロパティです｡

27
00:02:20,980 --> 00:02:22,240
‫リフレクションシステム｡

28
00:02:22,690 --> 00:02:31,060
‫リフレクションシステムを使うと､ この変数をブループリントに公開したり､ ガベージコレクションに参加したりといったことができるようになります｡

29
00:02:31,060 --> 00:02:36,400
‫つまり､ youプロパティを追加することで､ コンポーネントを作成する際に追加されるものになるのです｡

30
00:02:36,400 --> 00:02:44,860
‫このカプセル・コンポーネントは､ YOUカプセル・コンポーネント・タイプを使っているので､ コンパイラにこのタイプを知らせる必要があります｡

31
00:02:44,860 --> 00:02:48,250
‫カプセルコンポーネントが何であるかは､ デフォルトではわからない｡

32
00:02:48,250 --> 00:02:54,640
‫通常､ カプセル・コンポーネントが何であるかをコンパイラに伝えるには､ includeディレクティブでヘッダファイルを先頭に含めます｡

33
00:02:54,640 --> 00:02:59,680
‫アンリアル・エンジンのドキュメントで「カプセル・コンポーネント」を検索すると､

34
00:02:59,710 --> 00:03:08,950
‫ここにカプセル・コンポーネントについてコンパイラに伝えるために必要なヘッダーファイルを含めると書かれています｡

35
00:03:08,950 --> 00:03:13,000
‫あとは､ これを一番上に入れれば､ U.

36
00:03:13,000 --> 00:03:18,160
‫カプセルの部品型はコンパイラに認識され､ すべてがうまくいく｡

37
00:03:18,220 --> 00:03:25,720
‫しかし､ 一般的に､ このようなものをコーディングするときのグッドプラクティスは､ このヘッダーファイルをできるだけ小さくするようにすることです｡

38
00:03:25,720 --> 00:03:32,380
‫このファイルにヘッダーファイルを含めると､ プリプロセッサと呼ばれるプログラムがそのヘッダーファイルの内容をすべて取り込み､

39
00:03:32,380 --> 00:03:40,780
‫コメントなどの一部を取り除いて､ 文字通りそのヘッダーファイルの内容をすべてこのファイルに貼り付けます｡

40
00:03:41,050 --> 00:03:47,530
‫その結果､ そのインクルードファイルの内容をここに貼り付けるので､ このファイルは大きくなってしまうのです｡

41
00:03:47,530 --> 00:03:50,950
‫使うときだけ､ モノを入れたいと考えています｡

42
00:03:50,950 --> 00:03:56,740
‫では､ ここでベースとなる -- ヘッダファイルを含めないようにするにはどうすればよいのでしょうか｡

43
00:03:56,740 --> 00:04:02,380
‫さて､ C++ではフォワード宣言と呼ばれるものを使うことができます｡

44
00:04:02,380 --> 00:04:07,990
‫このカプセルコンポーネントの型は､ classキーワードで次のように宣言します｡

45
00:04:08,470 --> 00:04:18,010
‫コンパイラは､ 変数を宣言するたびに､ この型を緑色で表示します｡

46
00:04:18,010 --> 00:04:26,170
‫これはコンパイラにこれが型であることを伝えているので､ 「これは型として認識されません」というインテリセンス・エラーを出さなくなります｡

47
00:04:26,170 --> 00:04:28,150
‫さて､ これは不完全なタイプです｡

48
00:04:28,150 --> 00:04:34,150
‫実際にこの型を使って､ 関数や変数などのメンバにアクセスしたり､ この型のオブジェクトを構築しようとすると､

49
00:04:34,150 --> 00:04:38,560
‫不完全な型であるため､ エラーが発生します｡

50
00:04:38,560 --> 00:04:44,950
‫これらのことを行うには､ この型を使用する場所に含まれるヘッダーファイルが必要なので､ ヘッダーファイルを必要としないように､

51
00:04:44,950 --> 00:04:48,400
‫型のポインターを前方に宣言することができます｡

52
00:04:48,400 --> 00:04:53,230
‫しかし､ 特定のクラスを継承するためにヘッダーファイルが必要であることに注意する必要があります｡

53
00:04:53,230 --> 00:05:00,130
‫このクラスはpondを継承しており､ pondのヘッダーファイルがここで一番上に含まれていることに注意してください｡

54
00:05:00,130 --> 00:05:05,470
‫つまり､ 継承には､ 継承する型のヘッダーファイルが必要なのです｡

55
00:05:05,470 --> 00:05:09,100
‫そこで､ フォワード宣言について､ その理由を説明します｡

56
00:05:09,130 --> 00:05:17,020
‫例えば､ Base Ponというクラスがあり､ カプセル・コンポーネント型のポインタ変数を持つ必要があるとします｡

57
00:05:17,050 --> 00:05:22,060
‫これで､ カプセルコンポーネントはカプセルコンポーネントヘッダファイルになりました｡

58
00:05:22,060 --> 00:05:28,470
‫さて､ この型を実際に使うのは､ Uのオブジェクトを構築するときを基準にしている｡

59
00:05:28,480 --> 00:05:30,010
‫カプセルの成分タイプ｡

60
00:05:30,010 --> 00:05:36,820
‫つまり､ U型カプセルコンポーネントのポインタがあればいいのです｡

61
00:05:37,000 --> 00:05:45,160
‫今すぐ真実は､ Hに基づいている実際にはカプセルコンポーネントクラスの実装の詳細を必要としない｡

62
00:05:45,160 --> 00:05:51,820
‫つまり､ 関数がどのように定義されているか､ カプセル部品クラスの大きささえも知る必要はないのだ｡

63
00:05:51,850 --> 00:05:55,750
‫カプセルコンポーネントポインターは､ 他のポインターと同じサイズです｡

64
00:05:55,750 --> 00:05:57,250
‫ただの住所です｡

65
00:05:57,250 --> 00:05:58,810
‫今度はベースプランのクラスで｡

66
00:05:58,810 --> 00:06:01,420
‫カプセルの部品を組み立てたい｡

67
00:06:01,510 --> 00:06:09,790
‫そのため､ このオブジェクトを作成するために必要なメモリを配置するために､ カプセルコンポーネントのサイズを知る必要があるのです｡

68
00:06:09,790 --> 00:06:16,330
‫ですから､ カプセルコンポーネントヘッダーはベースポンカでは厳密には必要ありませんが､ ベースでは絶対に必要なのです｡

69
00:06:16,350 --> 00:06:24,970
‫ポークパイ よいプログラミングの習慣とは､ 実際に必要なヘッダのみを含めることです｡ つまり､ ベースプロダクトHでU型カプセルコンポーネントポインタを宣言して､

70
00:06:24,970 --> 00:06:41,020
‫カプセルコンポーネントを構築する際に､ aのサイズを知る必要があるので､ 実装の詳細が必要な部分にカプセルコンポーネントを含めるということです｡

71
00:06:41,310 --> 00:06:43,230
‫メモリ内のカプセル成分｡

72
00:06:43,350 --> 00:06:49,920
‫では､ 代わりにヘッダーファイルをbase pond FXにインクルードした場合の結果について説明します｡

73
00:06:50,010 --> 00:07:01,230
‫これまで見てきたように､ このようなことは絶対に可能です｡

74
00:07:01,260 --> 00:07:03,180
‫さて､ ここで問題が発生する｡

75
00:07:03,210 --> 00:07:07,390
‫ヘッダーファイルは､ 他のファイルからインクルードされることを前提に設計されています｡

76
00:07:07,410 --> 00:07:12,810
‫そこで､ ベースポンドHがあり､ その中にカプセルの部品が含まれているとします｡

77
00:07:12,810 --> 00:07:18,600
‫そしてさらにその先には他のクラスがあり､ ベースポッドにカプセルコンポーネントポインタを持たせたように､

78
00:07:18,600 --> 00:07:23,370
‫他のクラスにもベースポッドポインタを持たせるつもりです｡

79
00:07:23,400 --> 00:07:28,230
‫さて､ わざわざベースポーンポインタと他のクラスを前方宣言するのではなく､

80
00:07:28,230 --> 00:07:33,810
‫普通に宣言して､ 他のクラスにベースポーンを含めることにします｡

81
00:07:34,680 --> 00:07:43,190
‫そのため､ 現在はBase Pond Hだけでなく､ カプセルコンポーネントのヘッダーも含まれており､ そのヘッダーファイルにコピーされるコードが増える結果になっています｡

82
00:07:43,200 --> 00:07:47,820
‫さて､ 他のクラスはカプセル・コンポーネントを含むベース・アポイントを持っています｡

83
00:07:47,820 --> 00:07:56,400
‫つまり､ コンテンツやカプセルの部品もすべて他のクラスHの中に入っていて､ そこでは必要ないのです｡

84
00:07:56,400 --> 00:08:01,910
‫Hがベースについて知る必要がある他のクラスは､ カプセル・コンポーネントについて気にしない｡

85
00:08:01,920 --> 00:08:07,920
‫さて､ このパターンを続けて､ さらに別のクラスというクラスを作成し､ さらに別のクラスは､

86
00:08:07,920 --> 00:08:13,680
‫前方宣言ではなく､ 他のクラスの型のポインタを持つ必要があるかもしれないとします｡

87
00:08:13,680 --> 00:08:21,180
‫ある別のクラスHをさらに別のクラスHの中に入れ､ 今度はさらに別のクラスHの中に入れただけです｡

88
00:08:21,210 --> 00:08:27,840
‫ベースポンドやカプセルコンポーネントHのヘッダは必要ないにもかかわらず､ 他のクラスがそれらのヘッダファイルを内部に含んでいるため､

89
00:08:27,840 --> 00:08:32,730
‫さらに別のクラスでそれを取得したことになります｡

90
00:08:32,730 --> 00:08:40,140
‫そのため､ カプセル・コンポーネントのすべてのコンテンツのコピーがあり､ Hに基づいて､ さらに別のクラスで立ち往生して､

91
00:08:40,140 --> 00:08:46,620
‫ファイルが肥大化し､ コンパイル時間が長くなっています｡

92
00:08:46,620 --> 00:08:52,440
‫そのため､ 実際に必要とされる場所でヘッダーファイルをインクルードするのがよいでしょう｡

93
00:08:52,440 --> 00:08:59,610
‫カプセル・コンポーネントをbase upon CPPにだけ含めるようにすれば､ 後で他のクラスを作成して実際にbase

94
00:08:59,610 --> 00:09:05,340
‫podを使う必要があるときに､ そこにヘッダを含めることができますし､ base uponにはカプセル・コンポーネントが含まれないので､

95
00:09:05,340 --> 00:09:13,440
‫他のクラスには余計なコードが含まれないようになります｡

96
00:09:13,440 --> 00:09:18,810
‫そして､ 他のクラスを必要とする別のクラスを作ろうとするとき､ その別のクラスのhを実際に必要なCPPに含めることができ､

97
00:09:18,810 --> 00:09:30,270
‫さらに別のクラスのHが必要のない他のヘッダーファイルの内容で埋め尽くされることがありません｡

98
00:09:30,270 --> 00:09:38,670
‫ですから､ このようにカプセル・コンポーネントに依存するクラスがある場合､ その依存関係を最小限にするのがベストです｡

99
00:09:38,880 --> 00:09:42,570
‫そこで､ コンパイルエラーの作成に挑戦します｡

100
00:09:42,570 --> 00:09:44,970
‫コンパイルエラーを恐れてはいけないのです｡

101
00:09:44,970 --> 00:09:47,550
‫開発過程では当たり前のことなんです｡

102
00:09:47,550 --> 00:09:56,160
‫そこで､ 意図的に1つ生成し､ 戻ってclassキーワードを削除し､ 前方宣言のcapsule compなしでコンパイルすることにします｡

103
00:09:56,160 --> 00:10:04,080
‫コンパイルというのは､ Visual Studioのコードからコンパイルできるという意味で､ 通常のC++コンパイルと同じです｡

104
00:10:04,110 --> 00:10:11,670
‫その方法を学びました｡ また､ ファイルとVisual Studioのコードを保存するだけで､ ライブコーディングを開始することができます｡

105
00:10:11,670 --> 00:10:17,280
‫どちらでも構いませんし､ 一度一緒にやってみて､ 両方の方法でどうなるかをお見せします｡

106
00:10:17,280 --> 00:10:22,440
‫ライブコーディングを使用する場合､ 当然ながら､ Visual Studioのコードで見る出力とは異なり､

107
00:10:22,440 --> 00:10:27,270
‫ライブコーディングウィンドウで生成された出力を見ることになります｡

108
00:10:27,270 --> 00:10:34,260
‫コンパイルエラーが出るので､ コンパイルエラーのメッセージを見て､ 何を言っているのか確認してください｡

109
00:10:34,470 --> 00:10:38,070
‫これは､ 私たちが発生させるエラーに慣れるためです｡

110
00:10:38,070 --> 00:10:43,500
‫そしてこの後､ 前後して､ classキーワードでcapsule compを宣言します｡

111
00:10:43,620 --> 00:10:48,450
‫それが終わったら､ もう一度コンパイルしてください｡ 今度はコンパイルに成功するはずです｡

112
00:10:48,780 --> 00:10:51,060
‫ビデオを一時停止して､ これを試してみてください｡

113
00:10:53,520 --> 00:10:56,350
‫それでは､ このコードに少し手を加えてみましょう｡

114
00:10:56,370 --> 00:10:58,320
‫classキーワードを削除してみる｡

115
00:10:58,700 --> 00:11:03,540
‫さて､ それではコンパイルを試みたところ､ ターミナルに以下のような出力がありました｡

116
00:11:03,570 --> 00:11:09,300
‫最初に表示されるのはエラーで､ エラーコードが表示され､ capsule comp is not member of a base

117
00:11:09,300 --> 00:11:10,830
‫pawnと表示されます｡

118
00:11:10,860 --> 00:11:17,940
‫C declaration of a base pawnという注意書きがあるのですが､ その結果､ 他のエラーが出ていることがわかります｡

119
00:11:17,940 --> 00:11:23,390
‫そのため､ 学生がコンパイルしようとすると､ 複数のエラーが出て混乱することがよくあるようです｡

120
00:11:23,400 --> 00:11:28,560
‫つまり､ 一つのミスが連鎖的に伝播していくのです｡

121
00:11:28,560 --> 00:11:31,670
‫だからといって､ 大量のファイルを修正しに行く必要はありません｡

122
00:11:31,680 --> 00:11:34,410
‫このエラーは､ ここに一つの起源がある可能性があります｡

123
00:11:34,410 --> 00:11:36,420
‫エラーの原点はわかっている｡

124
00:11:36,420 --> 00:11:37,820
‫フォワード宣言が必要です｡

125
00:11:37,830 --> 00:11:45,150
‫では､ 通常のコンパイルとVisual Studioのコードの代わりに､ ライブコーディングを使用するとどうなるかを見てみましょう｡

126
00:11:45,150 --> 00:11:54,270
‫すぐに赤でビルドが失敗したと表示され､ ここでも同じように表示されます｡

127
00:11:54,270 --> 00:11:55,050
‫ここです｡

128
00:11:55,050 --> 00:11:59,310
‫カプセルコンプはベースポーンノートのメンバーではありません｡

129
00:11:59,340 --> 00:12:01,860
‫ベースポーンの宣言をご覧ください｡

130
00:12:01,860 --> 00:12:03,750
‫つまり､ ここでも同じことが言えるのです｡

131
00:12:03,750 --> 00:12:08,490
‫つまり､ どちらの場合でも､ forward宣言を忘れると､ このようなエラーが発生することになります｡

132
00:12:08,490 --> 00:12:17,340
‫これで､ どのようなものかを知ることができ､ 謎のコンパイルエラーメッセージを恐れることも少なくなりました｡

133
00:12:17,460 --> 00:12:24,990
‫そこで､ このエラーを修正するために､ カプセルコンポーネントを前方に宣言して､ 再度コンパイルを試みることにします｡

134
00:12:24,990 --> 00:12:27,780
‫そして､ 今度はエラーもなくコンパイルできました｡

135
00:12:27,870 --> 00:12:32,070
‫それでは､ 変数の前方宣言を忘れたときにどのような状態になるかを見てみましょう｡

136
00:12:32,100 --> 00:12:35,250
‫今後､ コンパイラーエラーが発生した場合は､ このことを念頭に置いてください｡

137
00:12:35,760 --> 00:12:41,490
‫というわけで､ まとめとして､ 新しいポインタを作るときの前方宣言について説明し､ CPファイルには使うものだけを入れればよく､

138
00:12:41,490 --> 00:12:49,020
‫Hファイルにはなるべく入れないようにしようということを学びました｡

139
00:12:49,050 --> 00:13:00,090
‫新しいポインタをforward declareする限り､ ヘッダファイルは必要ないこと､ 特定の型のオブジェクトを構築する場合はヘッダファイルが必要であることは分かっています｡

140
00:13:00,090 --> 00:13:09,780
‫そして､ 関数や変数などのメンバにアクセスするためにヘッダーファイルが必要です｡ また､ クラスを継承するためにヘッダーファイルが必要なこともわかりました｡

141
00:13:09,780 --> 00:13:11,460
‫そこにヘッダーファイルが必要なのです｡

142
00:13:11,580 --> 00:13:17,160
‫さて､ 型宣言の方法とポインタのカプセルコンポができたので､ 実際にカプセルコンポーネントオブジェクトを作成する準備ができましたので､

143
00:13:17,160 --> 00:13:21,840
‫次のビデオでそれをやってみましょう｡

144
00:13:22,200 --> 00:13:23,040
‫また､ お会いしましょう｡

