UE4の勉強記録

UE4の勉強の記録です。個人用です。

9章8節 カスタム化したSWidget/UWidgetを作成する その2

<前文>

f:id:kazuhironagai77:20180826115857p:plain

で勉強しています。今回は、前回勉強した「9章8節 カスタム化したSWidget/UWidgetを作成する」のまとめで忘れていた部分、SCompoundWidgetクラスはSWidgetクラスのサブクラスである事を考慮してもう一度、How it works…を読み直してみたいと思います。

正直、書き直すに当たって、結構悩んでいました。正しい事だけを記述するのであれば、このブログのような「勉強してみた。」形式の書き方は意味がありません。このブログの趣旨はこの教科書を勉強するに当たって、私が失敗しそれをどのように直して正しい解答を見つけたかをありのままで記録する事です。

この失敗の記録は、他のこの教科書を使用してUE4のC++を学習する人々にとって重要です。それは、私がした失敗を避ける意味においてもその失敗から学ぶ意味においてもです。

当然、ありのままを記録する訳ですから、常に正しい解答にたどり着ける場合ばかりではありません。しかし正しい解答にたどり着く過程は、正しい解答以上に大切であり、間違った解答にたどり着いた場合であったとしても、その過程を記録する事で、どこで間違ったのかを明確に出来るため、間違った解答でも価値があります。

よって今回、前回の内容を否定して考察をもう一度やり直す事がこのブログの趣旨に沿っているのか正直悩みました。しかし、SCompoundWidgetクラスはSWidgetクラスのサブクラスである事を考慮しないで、この節をまとめてしまっては片手落ちです。ので、兎に角やって見る事にしました。

<本文>

<目的>

今回は、前文で述べた通り、SCompoundWidgetクラスはSWidgetクラスのサブクラスである事実を考慮してもう一度、How it works…を読み直してみたいと思います。

<考察>

それでは、もう一度How it works…を読んでいきます。

f:id:kazuhironagai77:20180826120050p:plain

前回説明した通りです。

f:id:kazuhironagai77:20180826120117p:plain

f:id:kazuhironagai77:20180826120132p:plain

UWidgetクラスを使用しますが、最初にSWidgetクラスを作成します。と2.は言っていたのです。更に、actualと言って実際はSWidgetクラスそのものを作成するのではない事、(SWidgetクラスのサブクラスを継承したクラスを作成する。)を暗示していたのでした。

f:id:kazuhironagai77:20180826120155p:plain

ここから、前回は混乱し始めます。確かに、2.でSWidgetクラスについての解説をしたのに、突然、新しく作成するクラスについての解説が始まるから、混乱しても仕方がないかもしれません。しかし、SCompoundWidgetクラスがSWidgetクラスのサブクラスで、SWidgetクラスは直接継承出来ない事を既に知っている今回は、3.の解説の意味を正しく取れます。

まず、2.で述べたようにSWidgetクラスを継承したクラスを作成します。ただし、SWidgetクラスは直接継承する事は出来ないので、SWidgetクラスのサブクラスを継承したクラスを作成します。

以下に、SWidgetクラスのAPIに示されているSWidgetクラスのサブクラスを示します。

f:id:kazuhironagai77:20180826120347p:plain

SWidgetクラスを継承したクラスを作成するためには、これらのサブクラスの中から、今回の要求に最も近いサブクラスを選ぶ必要があります。3.によればそれは、SCompoundWidgetクラスだそうです。理由は、我々が今回、二つのウィジェットを一緒にして合成してCompound Structureにしたいからだそうです。

f:id:kazuhironagai77:20180826120412p:plain

ここで、SCompoundWidgetクラスについての簡単な解説をしています。難しく考える必要はなく、文字通りに理解すればいいだけです。「SCompoundWidgetクラスは、二つのwidgetを一つのwidgetにします。」と言っています。

あまり、関係ないですが、前回の3.の解説でスペルミスを見つけたので、直しておきます。

f:id:kazuhironagai77:20180826120500p:plain

f:id:kazuhironagai77:20180826120511p:plain

以下に示す5.から17.までは、SCompoundWidgetクラスを継承した実際のクラスの解説なので、前回と大きく変わる内容にはなりません。よって今回はスキップします。

f:id:kazuhironagai77:20180826120534p:plain

.

.

.

f:id:kazuhironagai77:20180826120556p:plain

18.からUWidgetクラスについての解説に成ります。

f:id:kazuhironagai77:20180826120655p:plain

多少、訳が荒い部分もありますが、特に問題はありません。18.の解説に対する考察も前回ので十分に思えるので今回は特に付け足しません。

f:id:kazuhironagai77:20180826120751p:plain

19.は18.の解説を補っています。「SWidgetのサブクラスを継承した我々が作成したクラスの宣言をUWidgetクラスを継承したクラスから行う必要があります。そのクラスの名前は、UCustomButtonWidgetとします。」と言っています。

f:id:kazuhironagai77:20180826120847p:plain

ここで言う、実際のSWidgetとは、SWidgetクラスのサブクラスから継承した我々が作成したクラスの事を指しています。これは2.の解説で述べているActual SWidgetと同じです。

ここから、前回は凄い迷走を始めてしまいますが、そのおかげでSWidgetクラスについての理解が高まったのですから、それはそれです。

20.は以下に示すコードの解説をしています。

f:id:kazuhironagai77:20180826121013p:plain

ここで宣言されたRebuildWidgetが実際のSWidgetのリファレンスを返します。ただし、RebuildWidgetは関数なので実際には、SWidgetのリファレンスを保持する訳ではありません。MyButtonのプロパティの一つがそれを保持しています。

f:id:kazuhironagai77:20180826121113p:plain

前回の解説で十分と思います。特に直す所や付け足す所はありません。

f:id:kazuhironagai77:20180826121309p:plain

特に直す所や付け足す所はありません。

f:id:kazuhironagai77:20180826121332p:plain

この部分に関する解説に対する考察は前回以上のものはありません。

f:id:kazuhironagai77:20180826121356p:plain

ここは、大きく直さないといけない部分があります。

前回、

     (ア)  RebuildWidgetは、UWidgetが関連するネイティブなウィジェットを再構築します。

     (イ)  SCustomButtonウィジェットインスタンスを構築するためにSNewを使用します。

     (ウ)  ネイティブなウィジェットの内部でUWidgetのOnButtonClikcedメソッドをButtonClickedデリゲートにバイントするためにSlateの宣言的なシンタックスを使用します。

と3つに分けて解説しましたが、まず(ア)の考察で、「...このUCustomButtonWidgetクラスで宣言されている新しいウィジェットの事」を

f:id:kazuhironagai77:20180826121545p:plain

と断言していますがこれは間違っています。ここで述べているUWidgetが関連するネイティブなウィジェットとは、実際のSWidgetの事です。それを再構築するために、MyButtonも使用されていますがそれは、実際のSWidgetを再構築するために一部分に使用されているだけです。

しかし、前回は24.のその後でこのレシピの全体像が見えて来たのですから、間違いも無駄ではないですね。

f:id:kazuhironagai77:20180826121608p:plain

前回の解説で特に問題はないと思います。

f:id:kazuhironagai77:20180826121822p:plain

前回は、FReplyについては忘れてしまったとありましたが、大筋に関わるところではないので今回もFReplyは無視します。

f:id:kazuhironagai77:20180826121859p:plain

前回の解説から特に変更はありません。ここから31.までも特に変更する内容は見つかりませんでした。

f:id:kazuhironagai77:20180826122013p:plain

前回、この解説の言いたい事が分からなくで、発狂していますね。もう本当に苦しかったです。しかし、今回勉強した新たな事実を踏まえてもう一度読んでみましょう。

この文章が異常に難しいのは、when の中にfor exampleがありその中にbecauseがあって更にその中にif necessaryがあり、その中のどれかをSo thatが修飾しているからです。色々考えて見ましたが、やっぱり分かりませんでした。まあ、この訳でも中らずと雖も遠からずでしょう。

<まとめ>

あまり、苦労せずにここまでこれました。やり直すのは、決心するのは大変ですが、前回の遺産がある分そんなに大変ではないですね。それではまとめてみます。

     (ア) インターアクティブな機能を持つウィジェットは全てSWidgetから作成しなければなりません。

     (イ) しかしSWidgetクラスは継承するように作られていないので、SWidgetクラスのサブクラスであるSCompoundWidgetクラスを継承してクラスを作成し、そのクラス内に2つのウィジェットを持たせます。

     (ウ) 一方で、(イ)で作成したクラスを宣言するために、UWidgetクラスを継承したクラスを作成します。

     (エ) (ウ)がUMG内で表示される新しいウィジェットになります。

以上です。

<おまけ>

なしです。