﻿1
00:00:03,970 --> 00:00:05,720
‫こんにちは､ お帰りなさい｡

2
00:00:05,740 --> 00:00:09,340
‫このビデオでは､ 戦車を高速化する方法について説明します｡

3
00:00:09,340 --> 00:00:13,030
‫戦車の移動速度を正確にコントロールしたい｡

4
00:00:13,030 --> 00:00:18,940
‫そして今は､ このデルタ位置のベクトルをローカルオフセットとしてadd actに渡しているだけで､

5
00:00:18,940 --> 00:00:22,450
‫タンクの移動速度を制御することはできません｡

6
00:00:22,450 --> 00:00:24,310
‫実はかなりゆっくり動いているんです｡

7
00:00:24,310 --> 00:00:29,200
‫そこで､ その速度を制御するための速度変数を作ることにします｡

8
00:00:29,200 --> 00:00:37,360
‫また､ 私たちのゲームはフレームごとにフレームレートが変化するため､ ゲームのフレームレートも考慮します｡

9
00:00:37,360 --> 00:00:40,360
‫実は､ 安定した動きが得られていないのです｡

10
00:00:40,360 --> 00:00:45,460
‫そこで､ そのフレームレートを考慮するために､ デルタタイムと呼ばれるものをお話します｡

11
00:00:45,730 --> 00:00:53,320
‫エディターで再生して､ 戦車を動かしても､ それが目に見えるわけではありません｡

12
00:00:53,320 --> 00:00:57,640
‫しかし､ 私たちの戦車はフレームからフレームへ一貫した速度で動いているわけではありません｡

13
00:00:57,640 --> 00:01:04,210
‫その理由は､ フレームレートが変化するためで､ ビューポートの左上には小さなドロップダウンがあります｡

14
00:01:04,210 --> 00:01:10,810
‫それをクリックすると､ show DPS PESの横にチェックボックスがあるのですが､ これはframes per secondの意味です｡

15
00:01:10,810 --> 00:01:15,940
‫これをチェックすると､ 右上にフレーム/秒が表示されます｡

16
00:01:15,940 --> 00:01:20,740
‫そして､ そのすぐ下には､ 最後のフレームから何ミリ秒経過しているか？

17
00:01:20,740 --> 00:01:23,560
‫そして､ これらの値はフレームごとに変化します｡

18
00:01:23,560 --> 00:01:29,170
‫再生ボタンを押してしまうと見逃してしまうかもしれませんが､ フレームレートが下がって､ また上がってくるのは､

19
00:01:29,170 --> 00:01:32,920
‫その序盤の段階で､ いろいろなことが起きていたからです｡

20
00:01:32,920 --> 00:01:39,820
‫役者全員がビギンプレイ機能を連呼していたし､ 世界観の裏設定もある｡

21
00:01:39,820 --> 00:01:49,060
‫今､ ゲームを始めると､ その120のアプリが120付近で推移しているにもかかわらず､ フレームごとに変化しているのです｡

22
00:01:49,060 --> 00:01:57,340
‫このため､ 動きが安定しないのは､ フレームレートが下がるにつれて､ これらのティックアップデートが呼び出される頻度が少なくなるからです｡

23
00:01:57,340 --> 00:02:02,860
‫そして､ この戦車を毎フレーム同じ量だけ動かすとしたら､ その一貫した動きを得るためには､

24
00:02:02,860 --> 00:02:06,040
‫フレームレートを一定に保つことが必要なのです｡

25
00:02:06,040 --> 00:02:11,860
‫さらにゲームが複雑になると､ フレームレートの変動がどんどんひどくなっていくんです｡

26
00:02:11,860 --> 00:02:17,320
‫そこで､ デルタタイムというものを使って､ しっかりと調整する必要があるのです｡

27
00:02:17,710 --> 00:02:20,020
‫では､ この謎のデルタタイムは何なのか？

28
00:02:20,020 --> 00:02:25,960
‫さて､ このタイムラインは､ 0秒から始まり､ 時間が経つにつれて増えていくとします｡

29
00:02:25,960 --> 00:02:31,240
‫さて､ 時間が進むとカチカチと音がしていましたが､ これはtick関数が呼び出されていることを意味します｡

30
00:02:31,240 --> 00:02:35,830
‫しかし､ ティック機能はあまり一貫性がないことに注意してください｡

31
00:02:35,830 --> 00:02:40,480
‫非常に急激に呼ばれることもあれば､ あまり呼ばれないこともあります｡

32
00:02:40,630 --> 00:02:46,840
‫これは､ コンピューターがフレームごとに計算を行う必要があり､ その計算がコンピューターのリソースを多く消費し､

33
00:02:46,840 --> 00:02:52,720
‫フレームレートが遅くなることがあるためです｡

34
00:02:52,750 --> 00:03:00,310
‫さて､ tick関数にあるこのデルタタイム変数は､ 最後のフレームから経過した時間の量です｡

35
00:03:00,310 --> 00:03:02,590
‫だからここでは0かもしれない｡  1秒

36
00:03:02,620 --> 00:03:07,270
‫CPUの使用率やその変動に本当に左右されます｡

37
00:03:07,270 --> 00:03:12,490
‫つまり､ CPUの使用率が変われば､ デルタタイムも変わるということです｡

38
00:03:12,490 --> 00:03:18,100
‫そしてこれは､ 1秒あたりのフレーム数が増えると､ 関数呼び出しの回数が増えるということです｡

39
00:03:18,100 --> 00:03:24,910
‫アクターローカルオフセットの追加を頻繁に呼び出すと､ 池の動きが速くなり､

40
00:03:24,910 --> 00:03:27,820
‫移動速度が一定になりません｡

41
00:03:27,820 --> 00:03:31,990
‫そこで､ 解決策として､ デルタ時間で動きをスケーリングすることにしました｡

42
00:03:31,990 --> 00:03:38,380
‫つまり､ デルタタイムを0とすると 1で､ 池を例えば1秒間に10cm動かしたい場合､

43
00:03:38,380 --> 00:03:46,030
‫その動きを0倍してスケーリングします｡ 1秒は､ フレーム更新時間0に必要な正確な移動量になります｡

44
00:03:46,030 --> 00:03:46,030
‫1秒

45
00:03:46,060 --> 00:03:52,930
‫ここで､ この部分のデルタタイムは小さく､ TICがより頻繁に呼び出されることを意味します｡

46
00:03:52,930 --> 00:03:56,260
‫ここでのデルタタイムを0とする｡  0 1秒

47
00:03:56,260 --> 00:03:59,530
‫だから､ TICはこっちの10倍は呼ばれているんですよ｡

48
00:03:59,530 --> 00:04:06,040
‫まあ､ 単純に動きを0倍にすればいいんですけどね｡  このフレームを01とすると､ 池を1秒間に10センチ動かすと､

49
00:04:06,040 --> 00:04:10,960
‫0. 0 1秒

50
00:04:10,960 --> 00:04:17,080
‫そのため､ TICが頻繁に呼ばれるようになったので､ 池をほんの少し動かしているのです｡

51
00:04:17,080 --> 00:04:24,520
‫こうすることで､ フレームレートの変化とは無関係に､ 池の動きが一定になるのです｡

52
00:04:24,670 --> 00:04:30,460
‫そこで､ VSEのコードに戻り､ この問題をどのように処理するかを考えてみましょう｡

53
00:04:30,490 --> 00:04:39,190
‫デルタ位置のベクトルがあり､ そのxはvalueに等しく設定されていますが､ valueをデルタ時間でスケーリングしたいことは分かっています｡

54
00:04:39,280 --> 00:04:50,800
‫そこで､ ここに少しコメントを入れて､ Xは値の倍､ デルタタイムに等しいとします｡ つまり､ 値をデルタタイムでスケーリングしたいのです｡

55
00:04:50,800 --> 00:04:56,890
‫フレームレートが非常に高い場合は特に､ デルタ時間自体が非常に小さな値であるため､ 一度これを行うと､

56
00:04:56,890 --> 00:05:00,400
‫値を非常に小さくすることになります｡

57
00:05:00,430 --> 00:05:02,770
‫だから､ これを何かでスケーリングする必要も出てくる｡

58
00:05:02,990 --> 00:05:11,110
‫Elseは一種の速度変数で､ この値を決めることで戦車の速度を制御することができるのです｡

59
00:05:11,120 --> 00:05:17,360
‫このように､ ちょっとした擬似コードを使って､ Speedの値を作成し､ デルタタイムの値を取得する方法を見つけることで､

60
00:05:17,360 --> 00:05:22,340
‫これを実装することができるのです｡

61
00:05:22,370 --> 00:05:27,440
‫そこで､ 移動関数からデルタ時間にアクセスする方法について説明します｡

62
00:05:27,440 --> 00:05:31,790
‫さて､ Unreal Engine には､ Delta 時間を取得するための方法が複数用意されています｡

63
00:05:32,150 --> 00:05:38,780
‫実際､ base upon Deltaにあるtick関数を見てみると､ timeはfloatの入力パラメータになっています｡

64
00:05:38,780 --> 00:05:45,140
‫つまり､ tick関数で作業している場合は､ すでにDelta時間にアクセスできますが､ tank DHCPでは､

65
00:05:45,170 --> 00:05:50,900
‫移動関数にその入力パラメータはありませんが､ 非現実的なエンジンにはその方法があるのです｡

66
00:05:50,900 --> 00:05:59,360
‫1つの方法は､ U gameplay staticsというクラスに存在するget world delta secondsという関数にアクセスすることです｡

67
00:05:59,360 --> 00:06:06,830
‫ゲームプレイスタティクスは､ その名の通り､ ゲームプレイのプログラミングを支援する静的な関数をたくさん持っています｡

68
00:06:06,860 --> 00:06:10,010
‫Get World Delta seconds はデルタタイムを返します｡

69
00:06:10,010 --> 00:06:11,600
‫今度は入力パラメータを持つようになりました｡

70
00:06:11,600 --> 00:06:14,900
‫ここでは､ ワールドコンテキストオブジェクトを受け取ります｡

71
00:06:14,900 --> 00:06:16,850
‫Unreal Engineではよく見かけますね｡

72
00:06:16,880 --> 00:06:20,930
‫多くの静的関数は､ ワールドコンテキストオブジェクトを必要とします｡

73
00:06:21,230 --> 00:06:24,800
‫ワールドは､ you worldという型のオブジェクトです｡

74
00:06:24,860 --> 00:06:27,260
‫それは､ 私たちのゲームの最上位オブジェクトです｡

75
00:06:27,260 --> 00:06:32,870
‫マップを表し､ ゲーム内のすべての関連オブジェクトが含まれています｡

76
00:06:32,870 --> 00:06:38,420
‫ワールドデルタ秒を取得するような静的な関数では､ どのワールドにいるのかがわからない｡

77
00:06:38,450 --> 00:06:45,200
‫この関数にどの世界にいるのかを教え､ その世界にアクセスしてデルタ時間値を取得できるようにする必要があります｡

78
00:06:45,230 --> 00:06:52,430
‫さて､ どの世界にいるのかを伝えるには､ その世界に存在するオブジェクトへのポインタを渡せばいい｡

79
00:06:52,430 --> 00:06:57,680
‫タンククラスで作業している間に､ キーワードであるthisを渡せばいい｡

80
00:06:57,710 --> 00:07:03,440
‫これは､ C++のどのクラスの内部でも使えるキーワードです｡

81
00:07:03,440 --> 00:07:10,370
‫このキーワードは､ 作業中の特定のオブジェクトのインスタンスへのポインタである｡

82
00:07:10,370 --> 00:07:16,220
‫つまり､ タンククラスで作業している場合､ これは今いるタンクへのポインタです｡

83
00:07:16,220 --> 00:07:26,570
‫そのため､ ワールドコンテキストオブジェクトを必要とする関数は､ 入力パラメータとしてこれを受け取ることができる場合が多い｡

84
00:07:26,570 --> 00:07:32,480
‫そのため､ ワールドデルタ秒を取得すると､ それがどのワールドにあるかがわかり､ 適切なデルタを取得することができるのです｡

85
00:07:32,480 --> 00:07:34,280
‫その世界の時間｡

86
00:07:34,280 --> 00:07:39,860
‫つまり､ get world delta seconds を -- クラスの中で呼び出す場合､ これを world context

87
00:07:39,860 --> 00:07:41,690
‫オブジェクトとして渡すことになる｡

88
00:07:42,410 --> 00:07:46,850
‫これで､ 戦車のスピードをコントロールするためのツールはすべて揃いましたね｡

89
00:07:46,880 --> 00:07:54,320
‫つまり､ 速度変数を作って､ これをfloatにして､ タンククラスのprivateセクションに置くということです｡

90
00:07:54,500 --> 00:07:59,750
‫開発中に調整できるように､ これをブループリントに公開します｡ つまり､ これにyouプロパティを与え､

91
00:07:59,750 --> 00:08:07,480
‫希望する公開レベルに対応する適切なyouプロパティ指定子を使用することになります｡

92
00:08:07,490 --> 00:08:12,800
‫さて､ MOV関数では､ コメントとして配置した疑似コードのビットがあります｡

93
00:08:12,800 --> 00:08:14,450
‫だから､ それを目安にしてください｡

94
00:08:14,450 --> 00:08:17,900
‫デルタ位置､ Fベクトル､ スケールを取ることになります｡

95
00:08:17,900 --> 00:08:19,880
‫デルタタイムでXなんです｡

96
00:08:19,880 --> 00:08:24,050
‫Uゲームプレイスタティクスを使用してデルタタイムにアクセスする方法を見たばかりです｡

97
00:08:24,050 --> 00:08:27,620
‫そして､ Xを速度変数でスケーリングすることにもなります｡

98
00:08:27,620 --> 00:08:35,240
‫さて､ 今回はgameplay staticsの関数を使うので､ gameplay statics用のヘッダーファイルをインクルードする必要があります｡

99
00:08:35,240 --> 00:08:42,950
‫さて､ アンリアルエンジンのドキュメントを使って､ 特定のクラスのインクルードを見つける方法を何度も紹介しました｡

100
00:08:42,950 --> 00:08:49,400
‫そこで､ Unreal Engineのドキュメントでゲームプレイのスタティックを検索して､ そのヘッダーファイルを見つけてみることに挑戦してみます｡

101
00:08:49,400 --> 00:08:54,290
‫そして､ もしそれが見つからない場合は､ このビデオのリソースにあるリンクを見つけるだけで､ ゲームプレイのスタティックのドキュメントが得られますが､

102
00:08:54,290 --> 00:08:57,920
‫自分自身でそれを見つけるようにしてください｡

103
00:08:57,920 --> 00:09:01,760
‫まず映像を一時停止して､ 今すぐ戦車のスピードをコントロールしてください｡

104
00:09:04,530 --> 00:09:04,890
‫なるほど｡

105
00:09:04,890 --> 00:09:11,460
‫そこで､ 私の疑似コードで､ デルタタイムと速度で値をスケーリングする必要があります｡

106
00:09:11,490 --> 00:09:14,130
‫そこでまず､ speed変数を作成します｡

107
00:09:14,130 --> 00:09:15,870
‫今､ hタンクに戻りました｡

108
00:09:15,870 --> 00:09:17,910
‫ここで､ スピードの変数を配置することができる｡

109
00:09:17,910 --> 00:09:26,730
‫しかし､ 以前の講義の練習問題で､ Base PondクラスにSpeedというfloatを追加したことを思い出してください｡

110
00:09:26,760 --> 00:09:29,730
‫今､ 私はこのベースポンドでスピードの変数を必要としません｡

111
00:09:29,760 --> 00:09:33,060
‫これはあくまで練習なので､ ここでは必要ないんですけどね｡

112
00:09:33,060 --> 00:09:38,790
‫実は､ 私が作ったこの他の30個のツは､ ユープロパティースペシファイアを実証するために必要ないのです｡

113
00:09:38,790 --> 00:09:43,590
‫そこで､ これらをすべてハイライトして､ ベースとなる池沼クラスから削除してしまいます｡

114
00:09:43,590 --> 00:09:44,910
‫もういらないんです｡

115
00:09:44,910 --> 00:09:46,430
‫だから､ もうないんです｡

116
00:09:46,440 --> 00:09:52,590
‫さて､ 池の水槽の設計図で､ この速度変数を参照したことも覚えておられるかもしれません｡

117
00:09:52,740 --> 00:09:54,990
‫そこで､ BP池の水槽を開放してみる｡

118
00:09:54,990 --> 00:09:59,250
‫そして､ このイベントグラフの中に､ 私が参照した速度変数があります｡

119
00:09:59,250 --> 00:10:06,720
‫もうこれは必要ないので､ これらのノードを削除して､ BP池水槽をコンパイルして保存してきます｡

120
00:10:07,020 --> 00:10:07,420
‫なるほど｡

121
00:10:07,440 --> 00:10:12,750
‫一通り片付けたら､ タンクに戻って速度変数を追加します｡

122
00:10:12,750 --> 00:10:15,660
‫そして､ ここはプライベートコーナーになります｡

123
00:10:15,660 --> 00:10:21,420
‫move関数のすぐ上に追加して､ speedというfloatにします｡

124
00:10:21,420 --> 00:10:24,270
‫では､ ここで初期値を与えてみます｡

125
00:10:24,270 --> 00:10:27,480
‫200Fで試して見ようかな｡

126
00:10:27,480 --> 00:10:34,020
‫しかし､ 開発中にエディタで編集できるようにしたいので､ 新しいプロパティ・マクロを取得し､

127
00:10:34,020 --> 00:10:39,330
‫インスタンスとデフォルトでこれを編集できるようにしたいと思います｡

128
00:10:39,330 --> 00:10:40,980
‫だから､ どこでも編集できるようにするんです｡

129
00:10:40,980 --> 00:10:43,980
‫さて､ こんなことしなくてもいいのにと思いつつ､ カテゴリーをあげてみました｡

130
00:10:43,980 --> 00:10:46,620
‫ムーブメントという新しいカテゴリーを作ってみます｡

131
00:10:46,680 --> 00:10:49,830
‫これでイベントグラフへの公開は任意となった｡

132
00:10:49,860 --> 00:10:54,660
‫イベントグラフでアクセスする必要はないと思うので､ 保留にします｡

133
00:10:54,660 --> 00:10:55,290
‫必要ならね｡

134
00:10:55,320 --> 00:11:02,320
‫将来的には､ ブループリント､ リード､ ライト､ ブループリントのリードオンリーで公開し､ そのメタでプライベートアクセスを指定することができます｡

135
00:11:02,490 --> 00:11:04,680
‫でも､ 今のところその気はない｡

136
00:11:04,710 --> 00:11:11,370
‫そこで､ 速度変数を持っていて､ ここ戦車DHCPでは､ 値を取って速度でスケーリングすることにしています｡

137
00:11:11,400 --> 00:11:17,970
‫最後に､ デルタタイムで値をスケーリングするのですが､ これにはゲームプレイのスタティックが必要です｡

138
00:11:18,150 --> 00:11:20,790
‫そこで､ Unreal Engineのドキュメントを紹介します｡

139
00:11:20,790 --> 00:11:27,810
‫私は先に行き､ あなたのゲームプレイの統計情報を検索し､ それはここにあるあなたのゲームのゲームプレイの統計情報です｡

140
00:11:27,810 --> 00:11:34,440
‫だから､ includeの行までスクロールして､ これをコピーして､ タンクCPに戻せばいいんです｡

141
00:11:34,470 --> 00:11:36,030
‫貼り付けることができます｡

142
00:11:36,030 --> 00:11:43,380
‫新しいゲームプレイスタティックにアクセスできるようになったので､ デルタタイムを取得できるようになったので､ あなたに掛けることにします｡

143
00:11:43,380 --> 00:11:52,140
‫ゲームプレイのスタティックはワールドデルタ秒を取得します｡ 先ほど見たように､ これにはワールドコンテキストオブジェクトが必要です｡

144
00:11:52,140 --> 00:11:56,610
‫ポップアップでワールドコンテキストオブジェクトを要求しているのもわかります｡

145
00:11:56,610 --> 00:11:58,500
‫だから､ 私はこれで合格です｡

146
00:11:58,590 --> 00:12:05,910
‫では､ Delta locations Xを値times, speed, times, delta timeに設定したので､ これをコンパイルしてみます｡

147
00:12:05,910 --> 00:12:07,980
‫というわけで､ コンパイルに成功しました｡

148
00:12:08,250 --> 00:12:14,040
‫エディターでBP Pond Tankに戻ると､ そこに私のスピードが表示されています｡

149
00:12:14,130 --> 00:12:20,970
‫そして､ ワールドで戦車のインスタンスを選択すると､ 詳細パネルで動きを検索すると速度があり､

150
00:12:20,970 --> 00:12:24,570
‫好きな値に設定することができるんです｡

151
00:12:24,570 --> 00:12:29,310
‫これを回して再生すると､ かなり動きが速くなるんです｡

152
00:12:29,310 --> 00:12:33,510
‫これが､ 変数をブループリントに公開するメリットなんですね｡

153
00:12:33,510 --> 00:12:37,920
‫試行錯誤して､ 自分に合ったスピードを見つけることができる｡

154
00:12:38,370 --> 00:12:40,380
‫よし､ それならいい感じだ｡

155
00:12:40,380 --> 00:12:43,770
‫もうFPSOを映すのはやめよう｡

156
00:12:44,010 --> 00:12:47,550
‫そして､ スピードの変数ができたので､ それを変更することができます｡

157
00:12:47,550 --> 00:12:52,170
‫そしてその変化は､ 私のポーンの動きに反映されます｡

158
00:12:52,710 --> 00:12:58,560
‫そこで､ タンクの移動速度を制御することにしました｡ ブループリントに公開する素晴らしい速度変数があり､

159
00:12:58,560 --> 00:13:03,780
‫その値を実験開発中に設定することができます｡

160
00:13:04,170 --> 00:13:08,940
‫また､ デルタ時間について学び､ なぜデルタ時間で動きをスケーリングすることが重要なのかについても学びました｡

161
00:13:08,940 --> 00:13:15,870
‫フレームレートが変わっても､ 戦車の動きはスムーズで一貫しているので､ フレームレートに依存しないのです｡

162
00:13:16,230 --> 00:13:21,150
‫さて､ セクションプランを振り返ってみると､ 最初の箇条書きはほぼ終わっています｡

163
00:13:21,150 --> 00:13:24,390
‫戦車を作ったので､ 世界中を移動することができます｡

164
00:13:24,540 --> 00:13:31,290
‫2つ目のポイントは､ WASDキーボード操作による入力と､ マウス入力にも対応することです｡

165
00:13:31,290 --> 00:13:39,240
‫WとSWの部分は押さえましたが､ AキーとDキーを使えるようにする必要があるので､ それらでタンクを回転させます｡

166
00:13:39,270 --> 00:13:42,330
‫だから､ これからの動画は順調に進んでいます｡

167
00:13:42,330 --> 00:13:45,690
‫タンクを動かす能力を仕上げることに取り組む｡

168
00:13:45,750 --> 00:13:46,740
‫また､ お会いしましょう｡

