<前文>
とうとう最後のレシピです。大抵の人は物事を途中で投げ出して最後までやり通しません。最後までやり通す人は極めて少数です。私は最後までやり通しました。私は子供の時は途中で諦めるタイプだったのですが自分でそれが凄く嫌いでした。そしてある時ある事に関して最後までやり通すコツを見つました。それは他の事にも結構通用して色々な事で最後までやり通す事が出来るようになりました。今回もそのコツを単に守っていただけで最後までやり通す事が出来ました。しかし最後までやり通すと結構後悔する事の方が多い事も気が付きました。大抵の人は物事を最後までやり通す人を尊敬しますが、実際は途中で投げ出した方が後悔しないで済む事が多い様です。今回は、後悔よりも満足感の方が勝っています。と言うかかなり最後までやって良かった。
ので、私流の最後までやり通すコツをまとめておきます。
- 頑張らない。頑張らないと出来ない事は長続きしません。どうしても頑張りたい人は前日の準備を頑張りましょう。ある参考書を勉強すると決めたとします。勉強時間は朝早起きして確保する事に決めました。ここで朝早起きする事を頑張る人は必ず途中で挫折します。頑張って早起きする事は自分に無理を強制しているからです。それなら前の日に頑張って1時間早く寝れるようにすべきです。それが出来れば自然に一時間早く目が覚めますから。
- 趣味にする。趣味なら楽しく出来ます。更に休憩時間、通勤時間、休日という膨大な時間を味方につけられます。
- 半分だけする。難しくて進捗が停止してしまう事は何かをしていると必ず起きます。誰かが奇跡的に助けてくれる事は割とありますが、無い時は半分だけやる事が良いです。例えばある問題をどうやって解いていいのか全く分からない場合、答えを見つける。その答えを理解する。に分解して答えを見つけるだけにまず集中するやり方です。
<本文>
<目的>
HTTPのAPIのIHttpRequestのオブジェクトを使用してダウンロードの進捗を示すプログレスバーを作成します。
<方法>
Step.0
取りあえず今回も新しいプロジェクトでやりますが、前回の内容が必要な事が判明したら前回のプロジェクトに追加する事にします。プロジェクト名は、Chapter12Part14とします。バージョンは4.22です。
教科書の説明だと、兎に角、この関数を使用して作成するそうです。
Step.1
サンプルコードも確認します。
Networking、Sockets、Messaging、MessagingRPCあたりのAPIは今回使用しそうですが教科書の方では書いていませんね。
私のコードには、HttpとUMGのみを追加します。
もし他のAPIが必要になったら随時追加します。
Step.2
はい。特にやり方は述べていないのでBPから作成します。
ProgressBarUMGと名付けました。
Progress barを追加しました。
ウーン。どこまで作成すればいいのか不明ですね。取りあえずレベル上に表示されるところまでは作成します。
こんな感じです。
Step.3
これは、前回のレシピのstep.3と全く同じですね。前回と全く同じ手順で作成します。前回のプロジェクトをそのまま使用しても良かったのですが、まあ復習も兼ねて作成します。
作成しました。
Step.4
これが、前回のIHttpRequestクラスのオブジェクトであるhttpの関数を呼び出す工程2ですね。
サンプルコードは以下の様になっています。
ここで大切なのはHttpProgressBarとBP上で作成したProgressBarをどう関係付けるかだと思います。思いますが最初はサンプルコードのコピーからやって行きます。
まず、サンプルコードの工程2の部分をコピーしました。エラーが表示されていますが先週同じコードのエラーを既に直しているので全く同じ方法で直します。
正し今回はLoggingファイルはサンプルコードをそのままコピーしました。
Cppのインクルードは変えましたが、hファイルの方は全く同じです。
それでは、HttpDialogについてやって行きます。
先ず、サンプルコードのhファイルをみると、
となっていますので、
私のコードにこの部分をコピーします。
案の定、UHttpDialogがエラーに成っています。何をインクルードすればいいのかをサンプルコードから調べると、
となっていました。
何、このクラス?サンプルコードから開いて見ると以下の様に成っていました。
ひょっとしてこれをStep.2で作成すべきだったの?
うーん。作り直しますか。
まず、HttpDialogクラスから作成します。
プログレスバーを追加します。
サンプルコードのHttpDialog.hの方は以下に示すインクルードが含まれていました。
これらもインクルードする必要があるのでしょうか?ウーン。分かりませんね。
サンプルコードではコンストラクターがありました。
のでこれも追加します。
エラーになってます。
このサイトによるとsuper()が必要と書かれていました。ので
Super(PCIP)を追加するとエラーが消えました。よく見たらサンプルコードの方はSuper(PCIP)が元々付いていました。
最後に残っている関数も追加しました。
ウーン。ここまでは出来たんですがこれが何を意味するのですか分からないです。勿論書いてある事は分かるのですがUMGとは結局、以下に示すようなUIデザインの事でしょう。
このクラスの何処にこのデザインの情報が入っているのでしょうか?
ウーン。教科書をひっくり返してみると、何か7章辺りでやったような感じなんですが全く覚えていません。
うーん。先に行ってしまいましょう。
Step.5
はい。
これだけ?
何か足りないような気がしますが。
<結果>
取りあえずplayを実行してみます。
何にも現れませんね。
思いっきりエラーに成っていましたね。それでは直していきましょう。
まず、最初にトライしたい事は、前回使用したIHttpRequestクラスのオブジェクトであるhttpの関数を呼び出す工程の3と
FHttpRequestCompleteDelegateクラスのオブジェクトであるdelegateの関数を呼び出す工程のどれか一つ
を追加する事です。
ビルドしてplayを実行するとエディターがクラッシュしました。
IHttpRequestクラスのオブジェクトであるhttpの関数を呼び出す工程の2を消してもう一度ビルドしてplayを実行すると、やっぱりクラッシュしました。
調べて見ると、以下に示すIHttpRequestクラスのオブジェクトであるhttpの関数を呼び出す工程の4がまるまる抜けていました。
追加してplayを実行すると今度は成功しました。
ので、もう一度、IHttpRequestクラスのオブジェクトであるhttpの関数を呼び出す工程の2を追加してビルドしてplayを実行しました。
今度はエディターがクラッシュする事なく正常に作動しました。
まず、play中の画面ですが、プログレスバー自身の表示はされません。
ただし、outputLogには以下に示すコードの実行された結果らしきものがプリントされていました。
コードを見ると、sentByteは常に0。recievedBytesは常に値を受け取っている。contentLenも常に0。なのでrecievedBytes/ contentLenであるpercentCompleteはエラーのようです。
2割ぐらいは出来ていると言う事でしょうか?
contentLenが0の理由から調べていきます。
使用したウェブアドレスはUE4のサイトなので、映像が常に切り替わっています。そのせいでcontentLenが測れていないのかもしれません。いくつかの別のウェブアドレスで試してみます。
一緒でした。sentByteはともかく、ContentLenの値が分からないと、ダウンロードの進捗が分からずプログレスバーは作成出来ません。ウーン。どうしましょうか?
サンプルコードを読んでいたらこんなコードがありました。
ブループリントから初期化してください。(ブループリントのコンストラクション図からこれをコンストラクトして下さい。)
これがcontentLenが0になる理由とは思えませんがプログレスバーが表示されない原因かもしれません。これを直してみましょう。
このサイトを参考にしてやってみます。
まず、HttpDialogクラスのBPの作成です。
Content内から右クリックしてリストを開きBlueprint Classを選択します。すると新しいリストが開きます。
開いたリストの中にあるAll Classesの下にあるボックスにHtttpDialogをタイプしてHttpDialogを選択します。
HttpDialogBPと名付けました。ダブルクリックしてHttpDialogBpのダイアグラムを開きます。
Variables内のStats下に作成したプログレスバーがありました。(本当にC++で作成したプログレスバーであるか確認するために名前をmyProgressBarに変更して確認しています。)
LevelBP上で、HttpDialogクラスのBPを初期化します。
Playを実行しましたが、プログレスバーは表示されなかったです。
やっぱり、何処かで、UMG内にプログレスバーを設置してそれとHttpDialogクラスのBPをバインドするなどの方法が必要と思われます。
うーん。これ以上の改変が必要となるとちょっと魔改造の域に入ってしまいそうですね。このブログの目的の一つはこの教科書を生徒の立場から評価する事ですのでこの辺で中止します。
<結論>
教科書のレシピの方法では、プログレスバーをPLAY画面に表示してそれをダウンロードの残り%を表示する事は出来ませんでした。出来ない原因が少なくとも2つ見つかりました。
1.contentLenが常に0。
2.UUserWidgetクラスから派生したUHttpDialogクラス内で作成したUProgressBarクラスのオブジェクトであるmyProgressBarをUMG上で表示する方法が不明。
1.についてはひょっとするとサーバー側の問題で、サーバー側で解決しないといけないのかもしれません。2については、UProgressBarクラスのオブジェクトであるmyProgressBarを使用しないで、UMG上にprogress Barを作成してその値をintかfloatでC++側から送れば解決しそうですが、そうするとレシピと似ても似つかないものになりそうなので止めます。
<おまけ1>
ラムダについてまとめると先週書きましたが、復習したらあんまり大した内容でなかったのでやりません。
<おまけ2>
最後は楽しく終われると思っていましたが何とも言えないビターな終を迎えてしまいました。まあ、サーバーとの関係はネットワームゲームの勉強でやらないといけませんしこんな触りの勉強でマスター出来る訳でもないのでこんなもんでしょう。