UE4の勉強記録

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

8章18節 ブループリントのための新しいグラフピンビジュアライザーを作成する.

<前文>

f:id:kazuhironagai77:20180507110030p:plain

で勉強しています。

今回は、「8章18節 ブループリントのための新しいグラフピンビジュアライザーを作成する。」を勉強します。

グラフピンビジュアライザーは、以下に示すブループリントで使用するノードの事のようです。

f:id:kazuhironagai77:20180507110104p:plain

***このブログは、このブログの読者が、教科書(Unreal Engine 4 Scripting with C++)を読んでいる前提で書かれています。この教科書を読まないで、このブログを読んでも理解不可能であると考えられます。ご了承ください。***

<本文>

<目的>

8章18節 ブループリントのための新しいグラフピンビジュアライザーを作成する。

<方法>

Step 0.

前回のプロジェクトをそのまま使用します。別名保存はしません。そのまま使用します。

Step 1.

f:id:kazuhironagai77:20180507110356p:plain

Visutal studioから普通に作りました。Packet Publish社のサンプコードを見ると、MyCustomAssetPinFactory.hは、Cookbookエディターフォルダー内に、保持されているので、同じ場所にファイルを保存します。

f:id:kazuhironagai77:20180507110425p:plain

Step 2.

f:id:kazuhironagai77:20180507110504p:plain

“以下のコード”は、教科書に書いている通りです。以下に、実際に書いたコードを示します。

f:id:kazuhironagai77:20180507110539p:plain

Step 3.

f:id:kazuhironagai77:20180507110611p:plain

新しいヘッダーファイル、SGraphPinCustomAssetを作成しました。PucketPublish社のSGraphPinCustomAssetは、サンプルコードは、MyCustomAssetPinFactory.hファイルを同じ場所にあるので、同様に、同じ場所に作成しました。

f:id:kazuhironagai77:20180507110647p:plain

Step 4.

f:id:kazuhironagai77:20180507110722p:plain

しました。

f:id:kazuhironagai77:20180507110756p:plain

Step 5.

f:id:kazuhironagai77:20180507110834p:plain

追加しました。

f:id:kazuhironagai77:20180507110939p:plain

ただし、MyCustomAssetDetailsCustomization.hファイルは、何処にも作成していないので、これ以降で、作成しない場合は、PucketPublish社のサンプルコードをつかいます。その場合、UE4Cookbookエディターと同じフォルダー内に保存しますので、Chapter8は省きました。

Step 6.

f:id:kazuhironagai77:20180507111040p:plain

追加しました。

f:id:kazuhironagai77:20180507111105p:plain

ただし、MyCustomAssetPinFactoryファイルがないので、エラーが表示されたままです。MyCustomAssetDetailsCustomization.hファイルを追加した時に、MyCustomAssetPinFactory.hファイルもインクルードされると考えられるので、とりあえずこのままにしておきます。

Step 7.

f:id:kazuhironagai77:20180507111244p:plain

以下に示すように、追加しました。

f:id:kazuhironagai77:20180507111311p:plain

エラーが表示されていますが、MyCustomAssetDetailsCustomization.hファイルを追加したら消えるのでしょうか?

Step 8.

f:id:kazuhironagai77:20180507111403p:plain

追加しました。

f:id:kazuhironagai77:20180507111440p:plain

Step 9.

f:id:kazuhironagai77:20180507111521p:plain

ここまで来て、教科書では、MyCustomAssetDetailsCustomization.hファイルを追加しないのが分かりましたので、ここで、追加します。

f:id:kazuhironagai77:20180507111559p:plain

f:id:kazuhironagai77:20180507111616p:plain

Packet Publish社のサンプルコードをそのまま使用しました。以下に示すように、DetailBuilderがエラーを表示しています。

f:id:kazuhironagai77:20180507111702p:plain

更に、FUE4CookbookEditorModule.hファイルの以下に示す箇所もエラーを表示しています。

f:id:kazuhironagai77:20180507111732p:plain

FUE4CookbookEditorModule.hファイルに、#include "MyCustomAssetPinFactory.h"を追加します。

f:id:kazuhironagai77:20180507111759p:plain

勿論、エラー表示は消えました。

f:id:kazuhironagai77:20180507111837p:plain

DetailBuilderのエラーは、良く分からないので、とりあえず、ビルドしてみました。

f:id:kazuhironagai77:20180507111915p:plain

また、ヘッダーファイルの順番を間違えていたので、エラーを食らいました。直してもう一度、ビルドします。

f:id:kazuhironagai77:20180507111943p:plain

やはり、DetailBuilderがエラーを吐いています。

f:id:kazuhironagai77:20180507112016p:plain

に変更してみると、

f:id:kazuhironagai77:20180507112042p:plain

とうとう、コンパイルしました。実行してみると、以下に示すように、エディターが起動しました。

f:id:kazuhironagai77:20180507112114p:plain

<結果>

Step 10.

f:id:kazuhironagai77:20180507112203p:plain

以下に示すように、新しい関数を作りました。

f:id:kazuhironagai77:20180507112229p:plain

Step 11.

f:id:kazuhironagai77:20180507112306p:plain

加えました。

Step 12.

f:id:kazuhironagai77:20180507112355p:plain

f:id:kazuhironagai77:20180507112408p:plain

ないです。

原因が分からないので、考察で、How it works…を一回勉強して、もう一度、考えてみます。と思ったら、原因が分かりました。

MyCustomAssetヘッダーファイルで、UClass()を、変更して戻してなかったからでした。

f:id:kazuhironagai77:20180507112448p:plain

UCLASS()を、以下のようにしました。

f:id:kazuhironagai77:20180507112514p:plain

もう一度、ビルドして実行します。そして、レベルブループリント内で、新しい関数を作り、そのinputにMyCustomAsset(reference)を選びます。

f:id:kazuhironagai77:20180507112547p:plain

今度は、完璧に出来ました。

Step 13.

f:id:kazuhironagai77:20180507112634p:plain

f:id:kazuhironagai77:20180507112655p:plain

出来ました。

<考察>

今回、5.まで解説して、大きな勘違いをしていた事に気が付きました。元々、このブログの目的は、間違いからどのように正しい答えに到達したかを記録するはずなのですが、余りに、グダグダなので、消して書き直しました。なので、構成が1.から5.までは、答えを知っているかのような書き方になっています。

今回も、How it works…を読んでいきます。

f:id:kazuhironagai77:20180507112829p:plain

最初に、2点断っておきます。Literal valuesは定数と訳しました。ブループリントピン(blueprint pin)は、以下に示すノードのサークルで囲ったピンの事と考えて訳しました。

f:id:kazuhironagai77:20180507112857p:plain

1.の文章を解説するためには、今回作成したブループリント上の関数、New Function 0を使用すると分かり易くなります。以下に、その関数のノードを示します。

f:id:kazuhironagai77:20180507112936p:plain

上に示した関数のノードでは、ピンの一つが、我々が作成したアセットタイプ、my custom assetになっています。更に、そのピンは、カラーピッカーとして表示されています。1.で説明している「オブジェクトがどのように表示されるか?」は、この場合、カラーピッカーとして表示されていると言うことです。次に、説明されている「このオブジェクトは、ブループリントのピン上に、定数として表示されています。」は、My custom asset のオブジェクトがピン上に表現されている事と考えられます。

ただし、ここで、定数と述べられていますが、Literal valueが定数と言う訳で正しいかどうかは 分かりません。カラーピッカーは勿論、定数ではありませんが、選ばれた色は、16進法で、RGBAそれぞれの数字として保存されるからです。その数字の事を、literal valueと呼ぶとしても、定数ではない(数字はユーザーが変えられる)ので、よく分からないです。

まだ、良く分からない事だらけですが、とりあえず、以下に、FGraphPanelPinFactoryクラスのコードを示します。(1.では、これらの事は、FGraphPanelPinFactoryクラスで行われていると書かれていますので。)

f:id:kazuhironagai77:20180507113040p:plain

f:id:kazuhironagai77:20180507113056p:plain

バーチャル関数は知っていますが、シングルは知りません。シングルトン用のクラスなのでしょうか?GraphPanelPinFactory.hファイルを見ると、コンストラクタもない、関数も一つしかない変なクラスです。なので、シングルは、コンストラクタのない、一個の関数のみのクラスと言う意味と考えておきます。

f:id:kazuhironagai77:20180507113134p:plain

やはり、この関数は、ピンのビジュアルを作成する事が目的です。Visual representationを、単にビジュアルと訳しました。

f:id:kazuhironagai77:20180507113209p:plain

4.は、以下に示した部分のコードの説明です。

f:id:kazuhironagai77:20180507113252p:plain

CreatePin関数は、UEdGraphPinクラスのインスタンスをパラメーターとしています。UEdGraphPinについてのUE4のAPI を見てみると、remarkがありませんでした。が、以下に示すように、このクラスの変数の一つに、DefaultObjectがあります。

f:id:kazuhironagai77:20180507113423p:plain

もし、このピンのデフォルト値が、オブジェクトなら、そのオブジェクトへのポインターを保存します。

まさしく、4.で述べた機能を担当する変数です。さらに、ここで、デフォルト値(default value)と、オブジェクトの事を値として、表現しています。Valueには、数字以外の意味も含ませる事があると分かります。(もしくは、ポインターvalueと表現?)

また「ピンとして表示されるオブジェクトについて…」とありますから、やはり、オブジェクトをピンで表示している事になります。

ここまで、読むと1.におけるliteral valueを定数と訳する事に対する疑問についてかなりの部分の答えが分かります。ここには、2つの解釈があると考えられます。

一つ目は、valueと言う単語には、数字で表せない場合も使用出来ると考えられる場合です。この場合は、数字としては示せないが、その他の形状で示せると考えられます。よって定数と言う訳は、間違っています。

二つ目は、そのオブジェクトに対するポインターとしてピン上で表すので、結果的には、ある数字になります。この数字は固定されるので、リテラル値(literal values)、定数という言い方も正しいと考えられなくはない。と言う考え方です。

どちらが正しい場合も、リテラル値(literal value)、もしくは、定数(literal value)と両方表記して、訳したほうが分かり易いと考えられます。

f:id:kazuhironagai77:20180507113559p:plain

以下にその部分のコードを示しますが、確かに、if (Pin->PinType.PinSubCategoryObject == UMyCustomAsset::StaticClass())となっていて、ピンのタイプがmyCustomAssetかどうかを確認しています。

f:id:kazuhironagai77:20180507113635p:plain

f:id:kazuhironagai77:20180507113649p:plain

If節の説明の続きです。

f:id:kazuhironagai77:20180507113731p:plain

Ifの条件に対して、trueの場合、以下のコードを実行します。

f:id:kazuhironagai77:20180507113757p:plain

f:id:kazuhironagai77:20180507113810p:plain

Ifの条件に対して、falseの場合、以下のコードを実行します。

f:id:kazuhironagai77:20180507113836p:plain

f:id:kazuhironagai77:20180507113910p:plain

SGraphPinCustomAssetは、我々の手で作成したクラスです。以下にコードを示します。

f:id:kazuhironagai77:20180507113935p:plain

f:id:kazuhironagai77:20180507113950p:plain

f:id:kazuhironagai77:20180507114003p:plain

以下に示す箇所が、SGraphPinCustomAssetクラスが、SGraphPinから継承した事を示すコードです。

f:id:kazuhironagai77:20180507114145p:plain

f:id:kazuhironagai77:20180507114107p:plain

ヘッダーファイルのコンストラクタを以下に示します。

f:id:kazuhironagai77:20180507114232p:plain

f:id:kazuhironagai77:20180507114303p:plain

GetPinColor関数とGetDefaultValueWidget関数を以下に示します。

f:id:kazuhironagai77:20180507114328p:plain

GetPinColor関数は、何故かヘッダーファイルで実装されています。(試しに、実装部をcppファイルに移したら、何故かエラーを食らってしまいました。ちょっと直せば、エラーは消せるはずですが、面倒くさいので、今回はパスしました。)

12.の解説では、GetDefaultValueWidget関数を実装します。とあるので、cppファイル内の実装部を以下に示します。

f:id:kazuhironagai77:20180507114353p:plain

f:id:kazuhironagai77:20180507114407p:plain

以下に、ColorPicked関数のコードを示しました。

f:id:kazuhironagai77:20180507114436p:plain

f:id:kazuhironagai77:20180507114502p:plain

以下に示す部分のコードの解説かもしれませんが、14.はどの解説をしているのか、今一不明なので、14.の考察は、パスします。

f:id:kazuhironagai77:20180507114232p:plain

f:id:kazuhironagai77:20180507114533p:plain

15.はGetDefaultValueWidget関数の解説です。以下に、もう一度、GetDefaultValueWidget関数のコードを示します。

f:id:kazuhironagai77:20180507114606p:plain

My custom assetクラスは、カラーピッカーのウィジェットが選ばれています。それが、ビジュアルとなります。

f:id:kazuhironagai77:20180507114640p:plain

16.は15.で示したコードの内容の簡単な解説です。

f:id:kazuhironagai77:20180507114702p:plain

17.はOnColorCommittedプロパティについての解説です。

f:id:kazuhironagai77:20180507114732p:plain

18.もOnColorCommittedプロパティについての解説です。

f:id:kazuhironagai77:20180507114756p:plain

19.は、ColorPicked関数についての解説です。以下にその関数のコードを示します。

f:id:kazuhironagai77:20180507114826p:plain

f:id:kazuhironagai77:20180507114843p:plain

と言う事は、New Function 0のMy Custom Assetタイプのピンは、オブジェクトからコネクトされる事でも、色の情報を設定出来ると言う事でしょうか?早速試してみました。

f:id:kazuhironagai77:20180507114927p:plain

出来ました。ただし、コネクト出来るオブジェクトのタイプは、my custom assetのみで、単純な色の指定は出来ないです。(20.で解説されている通りです。)

f:id:kazuhironagai77:20180507114958p:plain

以下に示す部分のコードの解説です。

f:id:kazuhironagai77:20180507115025p:plain

f:id:kazuhironagai77:20180507115037p:plain

NewObjectについての解説です。

f:id:kazuhironagai77:20180507115101p:plain

以下に示す部分のコードの解説です。

f:id:kazuhironagai77:20180507115132p:plain

f:id:kazuhironagai77:20180507115155p:plain

だそうです。

f:id:kazuhironagai77:20180507115219p:plain

以下に示した部分のコードの解説です。

f:id:kazuhironagai77:20180507115252p:plain

f:id:kazuhironagai77:20180507115304p:plain

25.で紹介したコードのさらなる解説です。GetSchema()関数についての解説です。

f:id:kazuhironagai77:20180507115359p:plain

25.で紹介したコードのさらなる解説です。TrySetDefaultObject ()関数についての解説です。

f:id:kazuhironagai77:20180507115433p:plain

28.の訳について少しだけ説明します。Extensionsを拡張と訳しました。Registraionは、そのままレジストレーションと訳しました。拡張(extention)は、今回付足したクラスの事を指しているとかんがえられます。レジストレージョン(registration)は何でしょうか?UE4では、あるクラスのインスタンスは、初期化せずregistrationするそうです。その事を指していると思われます。28.によれば、どちらの場合も、カスタム化されたビジュアルがある場合は、それを優先して実装し、そのようなものがない場合は、デフォルトのビジュアルとなる実装を作る必要があると述べています。

f:id:kazuhironagai77:20180507115525p:plain

29.の「これをするためには、」のこれは、カスタム化されたビジュアルがある場合はそれを優先して実装し、そのようなものがない場合はデフォルトのビジュアルとなる実装の事です。

f:id:kazuhironagai77:20180507115556p:plain

StartupModule関数に加えたコードは以下の通りです。

f:id:kazuhironagai77:20180507115621p:plain

PinFactory変数は、ヘッダーファイルで宣言されています。そのコードは以下に示します。

f:id:kazuhironagai77:20180507115646p:plain

うーん。何故これをすると、28.のカスタム化されたビジュアルがある場合はそれを優先して実装し、そのようなものがない場合はデフォルトのビジュアルとなる実装となるのでしょうか?全然分からないです。

f:id:kazuhironagai77:20180507115722p:plain

31.は以下に示した部分のコードの解説です。

f:id:kazuhironagai77:20180507115749p:plain

まず。「それを保存」とあります。それとは、なんでしょうか?上に示したコードが示すように、PinFactoryの事です。RegisterVisualPinFactory関数の機能は、「ビジュアルの表現を作成するために、PinFactoryを使うとエンジンに告げる。」と解説されています。

f:id:kazuhironagai77:20180507115818p:plain

32.は以下に示した部分のコードの解説です。ここからは、ShutdownModule関数の内に今回新たに加えたコードの説明です。ただし、ここですることは、PinFactoryをアンレジスターして、リセットする事で、PinFactoryのメモリーを開放する事です。

f:id:kazuhironagai77:20180507115848p:plain

f:id:kazuhironagai77:20180507115902p:plain

33.は以下に示した部分のコードの解説です。

f:id:kazuhironagai77:20180507115934p:plain

PinFactoryを開放します。

<まとめ>

今回は、我々が作成したクラスのオブジェクトをブループリント上のノード内のピンとしてセットする方法を勉強しました。さらに、このピンの表示方法もカスタマイズする方法も習いました。

f:id:kazuhironagai77:20180507120037p:plainf:id:kazuhironagai77:20180507120057p:plain

f:id:kazuhironagai77:20180507120112p:plain

<おまけ>

以下に示す点を直すことで、コードがコンパイルして実行出来るようになりました。

<問題>

  1. MyCustomAssetDetailsCustomizationファイルを自分で作成する必要があります。
  2. 教科書やサンプルコードの新しく作成するクラスの.cppファイルにおけるヘッダーファイルのインクルードの順番が間違っている。
  3. GetDetailsView().GetSelectedObjects();がエラーになり、コンパイルしない。
  4. My Custom Asset typeがタイプとして、ブループリント上で表示されない。

<回答>

  1. MyCustomAssetDetailsCustomization ファイルは、PucketPublish社のサンプルコードにあるので、それをそのまま使用します。
  2. cpp ファイルでは、そのcppファイルのヘッダーファイルを最初にインクルードします。
  3. GetDetailsView()->GetSelectedObjects(); に変更します。
  4. 以下に示すように、MyCustomAssetヘッダーファイルを変更します。

f:id:kazuhironagai77:20180507120206p:plain