<前文>
で勉強しています。
今回は、「8章18節 ブループリントのための新しいグラフピンビジュアライザーを作成する。」を勉強します。
グラフピンビジュアライザーは、以下に示すブループリントで使用するノードの事のようです。
***このブログは、このブログの読者が、教科書(Unreal Engine 4 Scripting with C++)を読んでいる前提で書かれています。この教科書を読まないで、このブログを読んでも理解不可能であると考えられます。ご了承ください。***
<本文>
<目的>
8章18節 ブループリントのための新しいグラフピンビジュアライザーを作成する。
<方法>
Step 0.
前回のプロジェクトをそのまま使用します。別名保存はしません。そのまま使用します。
Step 1.
Visutal studioから普通に作りました。Packet Publish社のサンプコードを見ると、MyCustomAssetPinFactory.hは、Cookbookエディターフォルダー内に、保持されているので、同じ場所にファイルを保存します。
Step 2.
“以下のコード”は、教科書に書いている通りです。以下に、実際に書いたコードを示します。
Step 3.
新しいヘッダーファイル、SGraphPinCustomAssetを作成しました。PucketPublish社のSGraphPinCustomAssetは、サンプルコードは、MyCustomAssetPinFactory.hファイルを同じ場所にあるので、同様に、同じ場所に作成しました。
Step 4.
しました。
Step 5.
追加しました。
ただし、MyCustomAssetDetailsCustomization.hファイルは、何処にも作成していないので、これ以降で、作成しない場合は、PucketPublish社のサンプルコードをつかいます。その場合、UE4Cookbookエディターと同じフォルダー内に保存しますので、Chapter8は省きました。
Step 6.
追加しました。
ただし、MyCustomAssetPinFactoryファイルがないので、エラーが表示されたままです。MyCustomAssetDetailsCustomization.hファイルを追加した時に、MyCustomAssetPinFactory.hファイルもインクルードされると考えられるので、とりあえずこのままにしておきます。
Step 7.
以下に示すように、追加しました。
エラーが表示されていますが、MyCustomAssetDetailsCustomization.hファイルを追加したら消えるのでしょうか?
Step 8.
追加しました。
Step 9.
ここまで来て、教科書では、MyCustomAssetDetailsCustomization.hファイルを追加しないのが分かりましたので、ここで、追加します。
Packet Publish社のサンプルコードをそのまま使用しました。以下に示すように、DetailBuilderがエラーを表示しています。
更に、FUE4CookbookEditorModule.hファイルの以下に示す箇所もエラーを表示しています。
FUE4CookbookEditorModule.hファイルに、#include "MyCustomAssetPinFactory.h"を追加します。
勿論、エラー表示は消えました。
DetailBuilderのエラーは、良く分からないので、とりあえず、ビルドしてみました。
また、ヘッダーファイルの順番を間違えていたので、エラーを食らいました。直してもう一度、ビルドします。
やはり、DetailBuilderがエラーを吐いています。
に変更してみると、
とうとう、コンパイルしました。実行してみると、以下に示すように、エディターが起動しました。
<結果>
Step 10.
以下に示すように、新しい関数を作りました。
Step 11.
加えました。
Step 12.
ないです。
原因が分からないので、考察で、How it works…を一回勉強して、もう一度、考えてみます。と思ったら、原因が分かりました。
MyCustomAssetヘッダーファイルで、UClass()を、変更して戻してなかったからでした。
UCLASS()を、以下のようにしました。
もう一度、ビルドして実行します。そして、レベルブループリント内で、新しい関数を作り、そのinputにMyCustomAsset(reference)を選びます。
今度は、完璧に出来ました。
Step 13.
出来ました。
<考察>
今回、5.まで解説して、大きな勘違いをしていた事に気が付きました。元々、このブログの目的は、間違いからどのように正しい答えに到達したかを記録するはずなのですが、余りに、グダグダなので、消して書き直しました。なので、構成が1.から5.までは、答えを知っているかのような書き方になっています。
今回も、How it works…を読んでいきます。
最初に、2点断っておきます。Literal valuesは定数と訳しました。ブループリントピン(blueprint pin)は、以下に示すノードのサークルで囲ったピンの事と考えて訳しました。
1.の文章を解説するためには、今回作成したブループリント上の関数、New Function 0を使用すると分かり易くなります。以下に、その関数のノードを示します。
上に示した関数のノードでは、ピンの一つが、我々が作成したアセットタイプ、my custom assetになっています。更に、そのピンは、カラーピッカーとして表示されています。1.で説明している「オブジェクトがどのように表示されるか?」は、この場合、カラーピッカーとして表示されていると言うことです。次に、説明されている「このオブジェクトは、ブループリントのピン上に、定数として表示されています。」は、My custom asset のオブジェクトがピン上に表現されている事と考えられます。
ただし、ここで、定数と述べられていますが、Literal valueが定数と言う訳で正しいかどうかは 分かりません。カラーピッカーは勿論、定数ではありませんが、選ばれた色は、16進法で、RGBAそれぞれの数字として保存されるからです。その数字の事を、literal valueと呼ぶとしても、定数ではない(数字はユーザーが変えられる)ので、よく分からないです。
まだ、良く分からない事だらけですが、とりあえず、以下に、FGraphPanelPinFactoryクラスのコードを示します。(1.では、これらの事は、FGraphPanelPinFactoryクラスで行われていると書かれていますので。)
バーチャル関数は知っていますが、シングルは知りません。シングルトン用のクラスなのでしょうか?GraphPanelPinFactory.hファイルを見ると、コンストラクタもない、関数も一つしかない変なクラスです。なので、シングルは、コンストラクタのない、一個の関数のみのクラスと言う意味と考えておきます。
やはり、この関数は、ピンのビジュアルを作成する事が目的です。Visual representationを、単にビジュアルと訳しました。
4.は、以下に示した部分のコードの説明です。
CreatePin関数は、UEdGraphPinクラスのインスタンスをパラメーターとしています。UEdGraphPinについてのUE4のAPI を見てみると、remarkがありませんでした。が、以下に示すように、このクラスの変数の一つに、DefaultObjectがあります。
もし、このピンのデフォルト値が、オブジェクトなら、そのオブジェクトへのポインターを保存します。
まさしく、4.で述べた機能を担当する変数です。さらに、ここで、デフォルト値(default value)と、オブジェクトの事を値として、表現しています。Valueには、数字以外の意味も含ませる事があると分かります。(もしくは、ポインターをvalueと表現?)
また「ピンとして表示されるオブジェクトについて…」とありますから、やはり、オブジェクトをピンで表示している事になります。
ここまで、読むと1.におけるliteral valueを定数と訳する事に対する疑問についてかなりの部分の答えが分かります。ここには、2つの解釈があると考えられます。
一つ目は、valueと言う単語には、数字で表せない場合も使用出来ると考えられる場合です。この場合は、数字としては示せないが、その他の形状で示せると考えられます。よって定数と言う訳は、間違っています。
二つ目は、そのオブジェクトに対するポインターとしてピン上で表すので、結果的には、ある数字になります。この数字は固定されるので、リテラル値(literal values)、定数という言い方も正しいと考えられなくはない。と言う考え方です。
どちらが正しい場合も、リテラル値(literal value)、もしくは、定数(literal value)と両方表記して、訳したほうが分かり易いと考えられます。
以下にその部分のコードを示しますが、確かに、if (Pin->PinType.PinSubCategoryObject == UMyCustomAsset::StaticClass())となっていて、ピンのタイプがmyCustomAssetかどうかを確認しています。
If節の説明の続きです。
Ifの条件に対して、trueの場合、以下のコードを実行します。
Ifの条件に対して、falseの場合、以下のコードを実行します。
SGraphPinCustomAssetは、我々の手で作成したクラスです。以下にコードを示します。
以下に示す箇所が、SGraphPinCustomAssetクラスが、SGraphPinから継承した事を示すコードです。
ヘッダーファイルのコンストラクタを以下に示します。
GetPinColor関数とGetDefaultValueWidget関数を以下に示します。
GetPinColor関数は、何故かヘッダーファイルで実装されています。(試しに、実装部をcppファイルに移したら、何故かエラーを食らってしまいました。ちょっと直せば、エラーは消せるはずですが、面倒くさいので、今回はパスしました。)
12.の解説では、GetDefaultValueWidget関数を実装します。とあるので、cppファイル内の実装部を以下に示します。
以下に、ColorPicked関数のコードを示しました。
以下に示す部分のコードの解説かもしれませんが、14.はどの解説をしているのか、今一不明なので、14.の考察は、パスします。
15.はGetDefaultValueWidget関数の解説です。以下に、もう一度、GetDefaultValueWidget関数のコードを示します。
My custom assetクラスは、カラーピッカーのウィジェットが選ばれています。それが、ビジュアルとなります。
16.は15.で示したコードの内容の簡単な解説です。
17.はOnColorCommittedプロパティについての解説です。
18.もOnColorCommittedプロパティについての解説です。
19.は、ColorPicked関数についての解説です。以下にその関数のコードを示します。
と言う事は、New Function 0のMy Custom Assetタイプのピンは、オブジェクトからコネクトされる事でも、色の情報を設定出来ると言う事でしょうか?早速試してみました。
出来ました。ただし、コネクト出来るオブジェクトのタイプは、my custom assetのみで、単純な色の指定は出来ないです。(20.で解説されている通りです。)
以下に示す部分のコードの解説です。
NewObjectについての解説です。
以下に示す部分のコードの解説です。
だそうです。
以下に示した部分のコードの解説です。
25.で紹介したコードのさらなる解説です。GetSchema()関数についての解説です。
25.で紹介したコードのさらなる解説です。TrySetDefaultObject ()関数についての解説です。
28.の訳について少しだけ説明します。Extensionsを拡張と訳しました。Registraionは、そのままレジストレーションと訳しました。拡張(extention)は、今回付足したクラスの事を指しているとかんがえられます。レジストレージョン(registration)は何でしょうか?UE4では、あるクラスのインスタンスは、初期化せずregistrationするそうです。その事を指していると思われます。28.によれば、どちらの場合も、カスタム化されたビジュアルがある場合は、それを優先して実装し、そのようなものがない場合は、デフォルトのビジュアルとなる実装を作る必要があると述べています。
29.の「これをするためには、」のこれは、カスタム化されたビジュアルがある場合はそれを優先して実装し、そのようなものがない場合はデフォルトのビジュアルとなる実装の事です。
StartupModule関数に加えたコードは以下の通りです。
PinFactory変数は、ヘッダーファイルで宣言されています。そのコードは以下に示します。
うーん。何故これをすると、28.のカスタム化されたビジュアルがある場合はそれを優先して実装し、そのようなものがない場合はデフォルトのビジュアルとなる実装となるのでしょうか?全然分からないです。
31.は以下に示した部分のコードの解説です。
まず。「それを保存」とあります。それとは、なんでしょうか?上に示したコードが示すように、PinFactoryの事です。RegisterVisualPinFactory関数の機能は、「ビジュアルの表現を作成するために、PinFactoryを使うとエンジンに告げる。」と解説されています。
32.は以下に示した部分のコードの解説です。ここからは、ShutdownModule関数の内に今回新たに加えたコードの説明です。ただし、ここですることは、PinFactoryをアンレジスターして、リセットする事で、PinFactoryのメモリーを開放する事です。
33.は以下に示した部分のコードの解説です。
PinFactoryを開放します。
<まとめ>
今回は、我々が作成したクラスのオブジェクトをブループリント上のノード内のピンとしてセットする方法を勉強しました。さらに、このピンの表示方法もカスタマイズする方法も習いました。
<おまけ>
以下に示す点を直すことで、コードがコンパイルして実行出来るようになりました。
<問題>
- MyCustomAssetDetailsCustomizationファイルを自分で作成する必要があります。
- 教科書やサンプルコードの新しく作成するクラスの.cppファイルにおけるヘッダーファイルのインクルードの順番が間違っている。
- GetDetailsView().GetSelectedObjects();がエラーになり、コンパイルしない。
- My Custom Asset typeがタイプとして、ブループリント上で表示されない。
<回答>
- MyCustomAssetDetailsCustomization ファイルは、PucketPublish社のサンプルコードにあるので、それをそのまま使用します。
- cpp ファイルでは、そのcppファイルのヘッダーファイルを最初にインクルードします。
- GetDetailsView()->GetSelectedObjects(); に変更します。
- 以下に示すように、MyCustomAssetヘッダーファイルを変更します。