﻿1
00:00:04,480 --> 00:00:05,530
‫お帰りなさい｡

2
00:00:05,560 --> 00:00:08,760
‫さて､ 今回のビデオでは､ ヒットイベントについてお話します｡

3
00:00:08,770 --> 00:00:17,560
‫弾が何かにぶつかったら､ それを検知して破壊するなどの対応ができればと思います｡

4
00:00:17,560 --> 00:00:22,710
‫あと､ ダメージを与えたり､ 爆発効果を起こしたりするのも､ 後で処理します｡

5
00:00:22,720 --> 00:00:26,350
‫では､ ここからはヒット商品について少しお話します｡

6
00:00:26,350 --> 00:00:29,440
‫私たちの弾丸はメッシュ成分を含んでいます｡

7
00:00:29,440 --> 00:00:37,450
‫タイプは静的メッシュコンポーネントで､ 静的メッシュコンポーネントは長い階層構造の中の1つのクラスであり､

8
00:00:37,450 --> 00:00:43,990
‫アンリアルエンジンシステムではその親の1つがプリミティブコンポーネントです｡

9
00:00:44,260 --> 00:00:48,100
‫以下は､ プリミティブコンポーネントのドキュメントページです｡

10
00:00:48,130 --> 00:00:54,910
‫プリミティブコンポーネントとは､ 一般的にレンダリングやコリジョンデータとして使用される､ ある種のジオメトリを含む､

11
00:00:54,910 --> 00:00:58,600
‫または生成するコンポーネントを指すと書いてありますね｡

12
00:00:58,600 --> 00:01:02,560
‫つまり､ 基本的にはシーンコンポーネントで､ いくつかの機能を追加したものです｡

13
00:01:02,560 --> 00:01:08,440
‫下にスクロールして階層を見ると､ you seen componentとそこから派生したyou primitive

14
00:01:08,440 --> 00:01:16,510
‫componentがあり､ さらに下にスクロールしてyouから派生した他のクラスもすべて見ることができます｡

15
00:01:16,510 --> 00:01:17,860
‫プリミティブコンポーネント｡

16
00:01:18,250 --> 00:01:24,280
‫ここで､ なぜこのような指摘をするかというと､ 静的メッシュコンポーネントは､ これらの機能をプリミティブコンポーネントから継承し､

17
00:01:24,280 --> 00:01:30,820
‫プリミティブコンポーネントにはヒットイベントを発生させる機能があるからです｡

18
00:01:30,850 --> 00:01:33,670
‫さて､ ヒットイベントを発生させるとはどういうことでしょうか｡

19
00:01:33,760 --> 00:01:45,160
‫さて､ 右の矩形で表されるジオメトリが世界にあり､ 左の円で表される静的メッシュコンポーネントを持つオブジェクトがあるとします｡

20
00:01:45,190 --> 00:01:52,660
‫さて､ 静的メッシュコンポーネントを持つこのオブジェクトがブロックに向かって移動している場合､ このコンポーネントがヒットイベントを処理するように設定されていれば､

21
00:01:52,660 --> 00:01:59,800
‫ブロックに衝突すると同時にヒットイベントが生成されます｡

22
00:01:59,800 --> 00:02:06,640
‫衝突イベントが発生すると､ 衝突したコンポーネントなど､ 衝突に関連するデータが生成されます｡

23
00:02:06,640 --> 00:02:09,640
‫つまり､ このブロックには静的なメッシュコンポーネントが含まれている可能性があります｡

24
00:02:09,640 --> 00:02:12,910
‫衝突時にその部品にアクセスすることができる｡

25
00:02:12,910 --> 00:02:19,120
‫また､ ヒットしたアクターにもアクセスでき､ ヘッドイベントではEFのヒット結果も生成されます｡

26
00:02:19,120 --> 00:02:25,090
‫Fのヒット結果について少し学びましたが､ ヒットした場所（世界の中の場所を表すFベクトル）など､

27
00:02:25,090 --> 00:02:30,790
‫ヒットしたイベントに関する多くの変数が含まれていることがわかりました｡

28
00:02:31,090 --> 00:02:33,460
‫これで投射物のメッシュができました｡

29
00:02:33,460 --> 00:02:37,690
‫静的メッシュコンポーネントポインタの型変数です｡

30
00:02:37,690 --> 00:02:44,380
‫さて､ この静的メッシュコンポーネントが世界の何かにぶつかるたびに､ それに反応するコードを用意したいと思います｡

31
00:02:44,380 --> 00:02:50,740
‫静的メッシュコンポーネントであるため､ プリミティブコンポーネントクラスを継承しています｡

32
00:02:50,740 --> 00:02:55,450
‫継承するものの一つに､ on component hitという変数がある｡

33
00:02:55,480 --> 00:02:58,750
‫さて､ ここでコンポーネントのヒットに関するドキュメントを紹介します｡

34
00:02:58,750 --> 00:03:05,320
‫When a Component Hits or is hit by something solidというイベントとして記述されています｡

35
00:03:05,320 --> 00:03:11,680
‫さて､ 下にスクロールしてみると､ コンポーネントのヒットにはタイプFのコンポーネントヒットのサインがあることがわかります｡

36
00:03:11,680 --> 00:03:17,770
‫そして､ これをクリックすると､ Fコンポーネントのヒットシグネチャが構造体であることがわかります｡

37
00:03:17,800 --> 00:03:25,660
‫さて､ 話を戻すと､ ドキュメントには､ コンポーネントが何か固いものに当たったり､ ぶつかったりしたときに呼び出されるイベントと書かれていることがわかります｡

38
00:03:25,660 --> 00:03:38,920
‫この現象は､ スイープを有効にしてセットロケーションを使用したキャラクターの移動や､ トリガーに歩いてぶつかるなどオブジェクトが重なるイベントの物理シミュレーションなどが原因で発生する可能性があります（オーバーラップイベントを参照）｡

39
00:03:38,920 --> 00:03:42,280
‫だから､ ヒットしたイベントもあれば､ 重なったイベントもある｡

40
00:03:42,280 --> 00:03:44,230
‫ヒット商品に拘る｡

41
00:03:44,470 --> 00:03:51,700
‫つまり､ on component hitはドキュメントではヒットイベントとして記述されており､ on component hitはF component

42
00:03:51,700 --> 00:03:56,410
‫hit signatureという型の構造体であることが分かっています｡

43
00:03:56,410 --> 00:03:57,550
‫今のところ順調です｡

44
00:03:57,550 --> 00:04:04,930
‫さて､ このコンポーネントヒット時のイベントは､ マルチキャストデリゲートと呼ばれるものでもあります｡

45
00:04:04,960 --> 00:04:10,270
‫マルチキャストデリゲートは､ 複数の機能をバインドすることができます｡

46
00:04:10,300 --> 00:04:14,200
‫複数のクラス上に存在する関数もあり得る｡

47
00:04:14,200 --> 00:04:22,600
‫そして､ これらの関数がこのマルチキャストデリゲートに束縛されると､ 呼び出しリストと呼ばれるものに追加される｡

48
00:04:22,600 --> 00:04:29,650
‫このヒットイベントが指示したときに､ すべての関数を呼び出すためのリストである｡

49
00:04:29,650 --> 00:04:35,500
‫このヒットイベントやマルチキャストデリゲートは､ 何かが起こったときにブロードキャストすると言います｡

50
00:04:35,500 --> 00:04:46,660
‫つまり､ 投射メッシュが何かにぶつかると､ このデリゲートは､ このデリゲートにバインドされている関数を持つすべてのクラスにブロードキャストします｡

51
00:04:46,690 --> 00:04:54,370
‫そのブロードキャストが送信されると同時に､ そのブロードキャストに応答して､ これらのバインドされた関数がすべて呼び出されるのです｡

52
00:04:54,370 --> 00:04:57,580
‫これは､ Unreal Engine の非常に強力な機能です｡

53
00:04:57,580 --> 00:05:03,610
‫衝突などのイベントを待つデリゲートと呼ばれるものを持つことができるのです｡

54
00:05:03,610 --> 00:05:03,970
‫そして､ その後に｡

55
00:05:04,100 --> 00:05:11,270
‫そして､ デリゲートはブロードキャストされ､ その結果､ ブロードキャストに応答してすべてのバインドされた関数が呼び出されることになります｡

56
00:05:11,270 --> 00:05:15,930
‫この繊細さに複数の機能を束ねることができるため､ マルチキャストと呼んでいます｡

57
00:05:15,950 --> 00:05:21,090
‫機能をバインドした複数のクラスにブロードキャストしている｡

58
00:05:21,110 --> 00:05:24,460
‫さて､ このデリゲートに関数をバインドするにはどうしたらいいでしょうか｡

59
00:05:24,470 --> 00:05:31,720
‫さて､ コンポーネントヒットには､ これを可能にするいくつかの機能があり､ その一つがadd dynamicと呼ばれるものです｡

60
00:05:31,730 --> 00:05:38,930
‫つまり､ ADDダイナミック関数を呼び出すときに必要なのは､ 2つのパラメータ､ つまり､ これを使うことができるユーザーオブジェクトと､

61
00:05:38,930 --> 00:05:46,000
‫コールバック関数､ つまり､ クラス上の何らかの関数のアドレスを渡すだけです｡

62
00:05:46,010 --> 00:05:54,770
‫そこで､ このon component hit delegateにアクセスしてadd dynamic関数を呼び出すと､ ユーザーオブジェクトとコールバックを渡すことができるようになります｡

63
00:05:54,770 --> 00:06:00,140
‫そして､ この結果､ そのコールバックがヒットイベントの呼び出しリストに追加されます｡

64
00:06:00,170 --> 00:06:07,280
‫コンポーネントがヒットすると､ このデリゲートをブロードキャストし､ このデリゲートにバインドされている関数が呼び出されます｡

65
00:06:07,280 --> 00:06:12,290
‫そこで､ このデリゲートにバインドするために､ コールバック関数を作成する必要があります｡

66
00:06:12,470 --> 00:06:18,290
‫ここにprojectileがあり､ ヒットイベントのコールバック関数が必要です｡

67
00:06:18,290 --> 00:06:23,090
‫では､ ここにプライベート関数を作って､ それをvoidにしましょう｡

68
00:06:23,150 --> 00:06:25,480
‫そして､ 私はこれを単純にヒットと呼ぶことにする｡

69
00:06:25,490 --> 00:06:30,820
‫これをどう呼んでもいいのですが､ onは十分に説明的だと思います｡

70
00:06:30,830 --> 00:06:40,460
‫このコールバック関数は､ ヒットイベントに対して正しいシグネチャを持つ必要があり､ つまり入力パラメータリストが非常に特殊である必要があります｡

71
00:06:40,460 --> 00:06:49,870
‫最初の入力パラメータはyouプリミティブコンポーネントポインタの型でなければならず､ それをhit compと呼ぶ｡

72
00:06:49,880 --> 00:06:52,160
‫これは､ 打撃を与える部品です｡

73
00:06:52,160 --> 00:06:56,170
‫今回は､ 投影メッシュを物にぶつけるようにします｡

74
00:06:56,180 --> 00:07:02,240
‫次のパラメータは､ Other Actorと呼ばれるアクターポインタです｡

75
00:07:02,540 --> 00:07:05,690
‫これはやられた役者になりそうだ｡

76
00:07:05,720 --> 00:07:12,950
‫次の入力パラメータは､ other compと呼ばれる別のあなたのプリミティブコンポーネントポインタです｡

77
00:07:12,980 --> 00:07:15,590
‫これが当たったもう一つの部品です｡

78
00:07:15,590 --> 00:07:21,410
‫つまり､ 他のアクターの静的メッシュコンポーネントを叩くと､ これがその静的メッシュコンポーネントになるわけです｡

79
00:07:21,410 --> 00:07:25,760
‫次に､ ノーマルインパルスと呼ばれるFベクトルです｡

80
00:07:25,820 --> 00:07:32,000
‫物理シミュレーションをしている場合､ 物理エンジンは衝突に対応してインパルスを適用します｡

81
00:07:32,000 --> 00:07:37,510
‫そして､ このfベクトルは､ そのインパルスの方向と大きさを表しています｡

82
00:07:37,520 --> 00:07:47,450
‫そして最後に､ 入力パラメータとして const F hit result という型があり､ これは const reference で､ hit という名前になっています｡

83
00:07:47,450 --> 00:07:54,380
‫そのため､ ヒットしたときに､ そのヒットに関するより多くの情報を含むヒット結果にアクセスすることができます｡

84
00:07:54,410 --> 00:07:59,150
‫さて､ これをデリゲートにバインドしているので､ U関数でなければなりません｡

85
00:07:59,150 --> 00:08:01,940
‫だから､ 私たちはあなたと一緒にこれをマークする機能です｡

86
00:08:01,940 --> 00:08:03,800
‫さて､ あなたは自分の機能を熟知しているはずです｡

87
00:08:03,800 --> 00:08:08,390
‫プロパティと同じように､ 変数ではなく､ 関数に適用されます｡

88
00:08:08,390 --> 00:08:09,590
‫とても大切なことですね｡

89
00:08:09,590 --> 00:08:12,890
‫コールバックは､ u関数でなければ動作しません｡

90
00:08:12,890 --> 00:08:14,600
‫これで､ 関数の宣言ができました｡

91
00:08:14,600 --> 00:08:17,330
‫それでは､ 関数を定義してみましょう｡

92
00:08:17,570 --> 00:08:19,090
‫そこで､ 投射材に戻ります｡

93
00:08:19,160 --> 00:08:24,410
‫CP tick関数の直下に､ この関数を定義しましょう｡

94
00:08:24,410 --> 00:08:32,240
‫この関数にボディを与え､ クラス名を関数名の直前に置くと､ コールバック関数ができあがります｡

95
00:08:32,510 --> 00:08:39,230
‫では､ このヒットした関数をデリゲートにバインドする準備ができましたので､ begin playでこれを行う必要があります｡

96
00:08:39,260 --> 00:08:45,380
‫コンストラクタで実行すると､ デリゲートがバインドされないなどの問題が発生することがあるため､ 早期に実行する必要があります｡

97
00:08:45,380 --> 00:08:47,330
‫ということで､ ここでやってプレイ開始です｡

98
00:08:47,330 --> 00:08:55,460
‫では､ 投射メッシュを用意し､ 矢印演算子を使って継承した変数にアクセスします｡

99
00:08:55,460 --> 00:09:03,470
‫コンポーネントヒット時に呼び出されるプリミティブコンポーネントで､ コンポーネントヒット時に機能追加ダイナミックを持っています｡

100
00:09:03,470 --> 00:09:09,740
‫不思議なことに､ オートコンプリートはadd dynamicには効かないので､ 関数名を全部入力する必要があります｡

101
00:09:09,740 --> 00:09:18,410
‫これは､ コンポーネントがヒットしたときにコールバックをバインドするために使用する関数で､ その関数を呼び出しリストに追加します｡

102
00:09:18,410 --> 00:09:30,290
‫まず､ ユーザーオブジェクトが必要ですが､ これは関数をバインドするクラスであるためです｡

103
00:09:30,290 --> 00:09:35,720
‫そこで､ operatorのアドレスとfunction a projectile on hitを使用することにします｡

104
00:09:35,720 --> 00:09:41,180
‫これで関数の結合が完了し､ ヒットイベントを生成する準備が整いました｡

105
00:09:41,420 --> 00:09:47,150
‫ここで､ UEEログでテストしてみると､ log temp warningを使うことができます｡

106
00:09:48,550 --> 00:09:52,120
‫そして､ テキストについては､ 単純にヒットで言えばいいのです｡

107
00:09:52,270 --> 00:09:58,570
‫そして､ 出力ログにこのように表示されれば､ オンヒット関数が呼ばれたことが分かります｡ これをコンパイルしてみましょう｡

108
00:09:59,020 --> 00:10:01,270
‫そこで､ ここに出力ログを開いています｡

109
00:10:01,270 --> 00:10:08,440
‫再生ボタンを押して弾を発射し､ そこにhit is calledのログメッセージが表示されます｡

110
00:10:08,440 --> 00:10:09,730
‫これが効いているんですね｡

111
00:10:10,450 --> 00:10:19,900
‫さて､ 余談ですが､ BP projectileに入り､ 詳細パネルでprojectile meshを選択すると､ collisionセクションまでスクロールすることができます｡

112
00:10:20,080 --> 00:10:30,760
‫そしてここでは､ コリジョン プリセットがすべてのダイナミックをブロックするように設定され､ コリジョン有効がこの設定コリジョン有効クエリと物理に設定されていることがわかります｡

113
00:10:30,760 --> 00:10:33,280
‫ヒットイベントには必要です｡

114
00:10:33,280 --> 00:10:36,700
‫ヒットしたイベントを問い合わせることができるようにする必要があります｡

115
00:10:36,700 --> 00:10:41,800
‫そしてもちろん､ 物理によって､ 物理エンジンが投射物のメッシュに作用するようになっています｡

116
00:10:41,800 --> 00:10:48,700
‫さて､ on hit 関数で on component hit delegate にバインドし､ 巨大なログを配置して動作していることを確認したところで､

117
00:10:48,700 --> 00:10:59,440
‫on hit 関数の入力パラメータのいくつかを理解するために､ この関数をもう少し詳しく調べてみたいと思います｡

118
00:10:59,440 --> 00:11:03,160
‫そこで､ オンヒット機能で､ YOUIのログをいくつか追加してください｡

119
00:11:03,160 --> 00:11:08,980
‫これらの入力パラメータのうち､ いくつかの名前をgit name関数を使って表示してほしいのです｡

120
00:11:08,980 --> 00:11:18,340
‫YUIのログを使って､ ヒットしたコンプ､ 他のアクター､ 他のコンプの名前を出力して､ ヒットしているこれらのオブジェクトの名前がわかるようにしてほしいです｡

121
00:11:18,340 --> 00:11:23,770
‫パーセントSE形式を使うのであれば､ Eログテキストマクロでtheを指定します｡

122
00:11:23,770 --> 00:11:30,700
‫例えば､ 他のアクターの名前を取得するには､ 他のアクター､

123
00:11:30,700 --> 00:11:36,880
‫get nameを呼び出し､ アスタリスクを先頭に置いて､

124
00:11:36,880 --> 00:11:45,550
‫Cスタイルの文字列を返します｡

125
00:11:45,550 --> 00:11:53,890
‫そこで､ ビデオを一時停止して､ Yui log in our on hit functionを使って､ ヒットしたコンプ､ 他のアクター､ 他のコンプの名前を現在表示するようにします｡

126
00:11:57,740 --> 00:11:58,040
‫なるほど｡

127
00:11:58,040 --> 00:12:02,570
‫で､ ここのプロジェクタイルCPで､ ここのyou logを使います｡

128
00:12:02,720 --> 00:12:10,610
‫そこで､ Yui logを使っているこの行をコピーして､ 文字列にはhit comp percent sと言い､

129
00:12:11,270 --> 00:12:22,910
‫テキストの直後にはhit comp get nameと言い､ このアスタリスクはF文字列からCスタイル文字列に変換するために必要です｡

130
00:12:22,910 --> 00:12:29,330
‫今度は同じ行を使いますが､ テキストを「other actor」に変えて､ 今度は「other

131
00:12:29,330 --> 00:12:32,480
‫actor」に名前を付けて呼びます｡

132
00:12:32,600 --> 00:12:39,950
‫そして最後に､ 他のコンプの呼び出しをプリントして､ 他のコンプに名前を入れてもらうんです｡

133
00:12:40,130 --> 00:12:47,630
‫では､ コンパイルしてエディタに戻り､ 再生ボタンを押して弾丸を発射し､ これを確認してみましょう｡

134
00:12:47,660 --> 00:12:50,780
‫ヒットコンプは投射メッシュであることがわかります｡

135
00:12:50,780 --> 00:12:56,180
‫このコンポーネントは､ デフォルトのサブオブジェクトを作成する際に､

136
00:12:56,180 --> 00:13:01,940
‫このコンポーネントに割り当てた名前を使っていることがわかります｡

137
00:13:01,940 --> 00:13:05,570
‫だから､ その名前が使われている状況の一つです｡

138
00:13:05,570 --> 00:13:09,830
‫ここで､ other actor flaw underscore zeroと書かれているのがわかると思います｡

139
00:13:09,830 --> 00:13:16,130
‫そして､ この欠陥となる静的メッシュのアクターは､ flowアンダースコア・ゼロという名前を持っているからです｡

140
00:13:16,130 --> 00:13:26,630
‫エンジンはアクターやコンポーネントの内部名称の末尾に数字を付けることがありますが､ 他のカンプをプリントアウトするときにも同じことが起こっているのがわかると思います｡

141
00:13:26,630 --> 00:13:33,110
‫flaw static mesh actor は static mesh component を持ち､ その名前は static mesh component zero です｡

142
00:13:33,110 --> 00:13:40,610
‫これで､ ヒット時のコールバック関数に入力されたパラメータについて､ もう少し詳しい情報が得られるようになりました｡

143
00:13:40,610 --> 00:13:48,620
‫そして､ ヒット・イベントに反応して何かをしたい場合､ C++でそれらのオブジェクトにアクセスできるので便利です｡

144
00:13:48,800 --> 00:13:57,650
‫まとめると､ ヒットイベントとそれがマルチキャストデリゲートとして実装され､ それらがどのように機能するかについて学びました｡

145
00:13:57,650 --> 00:14:05,030
‫On Hit と呼ばれる関数を作成し､ 投射物メッシュがプリミティブコンポーネントクラスから継承した on

146
00:14:05,030 --> 00:14:09,620
‫component hit デリゲートにバインドしています｡

147
00:14:09,620 --> 00:14:15,920
‫しかし､ このコールバック関数があれば､ 発射体を破壊するなどのロジックをこの関数内に配置することができるので､

148
00:14:15,920 --> 00:14:21,860
‫簡単に破壊できることがわかりました｡

149
00:14:21,860 --> 00:14:24,080
‫ですから､ それは今後の動画で扱います｡

150
00:14:24,080 --> 00:14:32,270
‫とりあえず､ これまで学んだUnreal Engine C++の中でもより複雑な分野の一つなので､ 自分をほめてあげてください｡

151
00:14:32,480 --> 00:14:33,890
‫次の動画でお会いしましょう｡

