BLOGブログ

2017.04.05UE4UE/ Blueprint

[UE4] 関数ライブラリとマクロライブラリの上手な活用

みなさんはブループリントのマクロライブラリや関数ライブラリは活用していますか?

今回は、違いがよく分からないやという人や、一応使ってはいるものの特に意識せずに運用している人に向けて一歩踏み込んだ内容でお届けしたいと思います。

まずは早速それぞれのライブラリに関して簡単にご紹介します。

※ちなみに関数とマクロの違いについては、こちらのスライドの42ページ以降に軽く解説しています

 

関数ライブラリとは

どこからでもアクセスできる色んな関数を一か所にまとめて持つことができるブループリントです。

【詳細】

  • 通常のブループリントと違い、変数を保持することができず、イベントグラフも存在しません。マクロも作れず、関数のみ作成可能です。
  • この中に書いた関数は、どのブループリント、それこそアクターやレベル問わず使えるようになります
  • 親クラスはBlueprintFnctionLibraryで、さらにその親はObject型、つまりアクターではないためにレベルに直接配置したりはできません。
    むしろこの場合は、わざわざレベルに配置する必要がない、といった方がよいでしょう。
  • 中身に書く関数は、通常のブループリントに書く関数と全く同じなので、出来る事、できない事は同じです。
    ローカル変数が使えるのも同じ、内部で使えるノードの性質も同じです。つまりLatentノードが使えないのも同じです。

 

マクロライブラリとは

どこからでもアクセスできる色んなマクロを一か所にまとめて持つことができるブループリントです。関数ライブラリと同じですね。関数ライブラリのマクロ版だと思ってください。

【詳細】

  • こちらも変数の保持ができず、イベントグラフも存在しません。関数が作れず、マクロのみ作成可能です。
  • この中に書いたマクロは、関数ライブラリ同様どのブループリントからでも使えるようになります。
  • 関数ライブラリと違い、親クラスを自由に選択する事ができます。
    親クラスの内容次第で使えるノードの内容が違ってくるので注意が必要です。この辺りは後で詳しく説明します。
  • 中身に書くマクロは、通常のブループリントで書くマクロと全く同じなので、出来る事、できない事は同じです。

 

さて、ここからが本題です。では実際にこれらを活用しようとした場合に、どんなことに気を付けるべきでしょうか。

 

注意すべき点

ブループリントはアセット参照などを含めると依存関係が発生します。これは関数ライブラリ、マクロライブラリも例外ではありません。そしてライブラリは色んなアクターが使う事が想定されるので、そのライブラリに不必要なアセットが依存して含まれてしまうと、ゲーム中にアクターを生成する際、芋ずる式にアセットがロードされてしまい、実際には読み込む必要がないアセットまでもが読み込まれて無駄にメモリを圧迫したり、ロードに無駄な時間がかかってしまいます。なので、極力依存関係が発生しないように作るか、もし依存関係が発生してしまう場合には、ライブラリを分けた方がよいです。

これを踏まえて考えると、ライブラリは1つだけではなく、用途によって複数用意しておくとよいでしょう。

例えばイベント発生時に使うライブラリであったり、キャラクターのアクション時に使うライブラリ、レベル操作を行う時に使うライブラリなど、様々なものが考えられます。

ただ、小規模のプロジェクトであればそこまで分ける必要はないかもしれません。分けたことにより関数やマクロを一つの場所にまとめるという管理、利便性のメリットが薄まるため、メリットデメリットをよく考えて運用方針を決めることをお勧めします。

ちなみにアセットの依存関係はライブラリも他のブループリント同様にサイズマップやリファレンスビューアーを使う事で簡単に確認する事ができます

 

関数ライブラリ内でマクロライブラリを使用する

マクロライブラリ内で関数ライブラリの関数を使用する事は可能です。では逆に関数ライブラリ内でマクロライブラリ内のマクロを使用する事は可能でしょうか?

答えは親クラスにあります。関数ライブラリの親クラスはBlueprintFnctionLibraryで、その親はObject型になります。という事はつまり、Object型が親クラスのマクロライブラリは使用できますが、それ以外が親になっているマクロライブラリは使えないという事になります。

ではマクロライブラリはObject型を親クラスにして作成した方がいいのかというと、そういうわけにもいきません。Object型を親にするという事は、DelayなどのActorで定義されているノードがそのマクロライブラリ内で使えないという事になります。

マクロライブラリを作成するときはこういった点も考慮して親クラスを決めていきましょう

 

マクロの多用は危険?

マクロは複雑になりがちなノードを綺麗にまとめるのに大変便利です。視認性を良くするためにも積極的にガンガン使っていきましょう!…そう思っていた時期が私にもありました。

過ぎたるは猶及ばざるが如しといいますが、大抵の事は良かれと思ってやり過ぎるとよくない事になります。ではマクロに関しては多用し過ぎるとどうなるか。それはやはりパフォーマンスまわりに影響するでしょう。

マクロによってイベントグラフがすっきりして、一見簡単な処理を行っているように見えます。ですが実際にはブループリントコンパイルが走ると、内部的にはマクロの中身が展開されてそのブループリントの中身は実は膨大なノードの量になってしまっていた、なんて事が起きかねません。マクロの中で別のマクロを使っていて、さらにその中でも別のマクロを…となるともはや実際のノード数は誰も把握していないなんて状況になるかもしれません。そんなブループリントが書かれているアクターをレベルに大量に配置してしまったら、やはりパフォーマンスは落ちてしまいます。

ではそうならないようにどうすればいいのでしょうか。それはコンパイル時に展開されるマクロを使うのではく、可能であれば関数にしてしまう事です。分岐などイベントの流れを制御するのはやはりマクロにしてしまうのが見やすいですが、それ以外の、例えば一連の処理をただまとめるだけであれば、それはマクロではなく関数によってまとめた方がよいでしょう。

 

これらの事を頭の隅に置いて、あらかじめマクロライブラリや関数ライブラリを作成、運用していくと、開発後期になってメモリを不要に使っている、ロード時間が長い、パフォーマンスが遅い、などの現象に頭を抱えながら涙目になってブループリントのリファクタリングをする必要が少しは減るかもしれません。