[UE4]Blueprintアンチパターン その1 -IsValidノード+Selectノード-
今回は、ゲーム制作を通して実際に遭遇したBlueprintのアンチパターンについて紹介したいと思います。
IsValidノードをSelectノードに繋ぐ
まず、次のようなnull safe constなGetTestStringという関数を作ります。
次に、レベルブループリント上で次のように繋ぎます。
NullActorがValid(非Nullでキル保留中でない)ならGetTestString関数の結果を、Invalid(Nullもしくはキル保留中)なら定数のNULLを画面に出力する、という一見自然そうな実装に見えます……が、これを実行すると、NullActorがNullのとき、エラーを起こします。
図1 GetTestString |
図2 IsValidノードをSelectノードに繋ぐ |
何故でしょうか?
実はSelectノードはTrueとFalseの両方の結果を一度に評価します。よって、NullActorがNullであってもGetTestStringを無理やり評価してエラーを起こしてしまっているのです。
実はSelectノードはTrueとFalseの両方の結果を一度に評価します。よって、NullActorがNullであってもGetTestStringを無理やり評価してエラーを起こしてしまっているのです。
さきほどと違う点は、GetTestStringの代わりにGetDisplayNameを繋げているところです。これを実行しても、エラーが起きることはありません。
何故でしょうか?
それはGetDisplayNameが静的なnull safe関数であるからです。この『静的な』が非常に重要で、例えばGetTestStringをnull safe const関数であっても、Blueprint上で呼び出すと{1}エラーを起こしてしまいますが、static関数であればエラーを起こさず呼び出すことができるようです。
実はIsValidも同じように静的なnull safe関数として実装されていて、これがNullActorがNullであってもエラーを起こさない理由となっています。
何故でしょうか?
それはGetDisplayNameが静的なnull safe関数であるからです。この『静的な』が非常に重要で、例えばGetTestStringをnull safe const関数であっても、Blueprint上で呼び出すと{1}エラーを起こしてしまいますが、static関数であればエラーを起こさず呼び出すことができるようです。
実はIsValidも同じように静的なnull safe関数として実装されていて、これがNullActorがNullであってもエラーを起こさない理由となっています。
話は戻りますが、このようなパターンに遭遇した場合、どのように解決すべきでしょうか。私は次のようにしました。
実行ピン数が増えてしまうのが少し気になりますが、これならNullTestActorがNullのとき、GetTestStringを評価することはありません。
図4 代替案 |
もしくは、GetTestStringをBlueprintFunctionLibrary上に実装することでも実現できます。
{1} C++の場合、nullポインタをデリファレンスしない限り、オブジェクトがnullであったとしてもnull safe const関数はエラーなく呼び出せます
この記事は次のバージョンで作成されました。
Unreal Editor(4.15.1-3348071+++UE4+Release-4.15)
コメント
コメントを投稿