依存関係とは
UnrealEngineでは、「アセット」と呼ばれる単位でデータを管理しています。
スタティックメッシュやスケルタルメッシュ、テクスチャ、マテリアル、アニメーション、サウンド、BPクラスなど、これらは全て「アセット」です。
(Windowsのエクスプローラーからプロジェクトを見たとき、拡張子が.uassetのものがアセット)
そしてこれらアセットは必ずしも単体で成り立っているわけではなく、他のアセットと組み合わさって作られていることがほとんどです。
例えば、キャラクターBPクラスはキャラモデルとしてスケルタルメッシュを使用しています。さらに、スケルタルメッシュは見た目の制御のためにマテリアル、動きの制御のためにアニメーションのアセットを使用します。
このように、あるアセットAが成り立つために他のアセットBを利用している場合、「アセットAはアセットBに依存している」と言い、このような関係を「依存関係」といいます。
ゲームを作る以上アセットが依存関係を持つことは避けられませんが、これは必要最小限にとどめることが望ましいです。
それはなぜかというと、依存関係を持っているアセットは以下のような性質を持つからです。
- アセットAのロード時、アセットBもまとめてロードされる
→必要以上の依存関係があると本来不必要なアセットまでロードしてしまいロード時間が伸びてしまう。 - アセットBが変更されると、アセットAに影響が生じる
→アセットの内容を変更してバグが生じた場合、依存関係を持っているアセット全てをデバッグ範囲に含める必要がある。 - アセットAから、アセットBの内容に変更を加えることができる
→アセットBが意図しない変更をアセットAで行われてしまい、バグが生じる危険性がある。
このように、必要以上の依存関係をアセットに持たせてしまうとゲームのパフォーマンスや開発効率に多大な悪影響を及ぼしてしまうことがあります。
必要以上の依存関係はとりわけBPクラス同士で発生しやすく、BPでコードを書く際には注意を払う必要があります。
というわけで、BPでコードを書く際に依存関係を必要最小限にとどめるためのテクニックを以下でいくつか解説していきます。
BPクラスへの参照
変数や関数、イベントの引数、返り値などにBPクラスへの参照型を使用すると依存関係が発生します。
この依存関係を切る方法は簡単です。
参照しているBPクラスの親クラスをさかのぼって、抽象度の高いC++クラスへの参照型としましょう。
C++クラスはアセットではないので、依存関係を切ることができます。
これを行った場合、もともと参照していたBPクラス固有の変数や関数などにアクセスすることができなくなりますが、後に解説するBPインターフェースというものを用いることで解決できます。
Cast
BPにはCastというノードがあります。
Castは抽象度の高いクラスへの参照を指定したクラスへの参照として解釈するためのノードです。
上記の例では、GetPlayerCharacterで取得したCharacter型の参照をCastでBP_Player型として解釈しなおすことでBP_Playerの変数にアクセスしています。
ひとつ前の節で行ったことと逆のことをしているので、当然依存関係が発生します。
依存関係を切るには、Castを使用せず抽象的な参照のままでコードを書く必要があります。
BPインターフェース
ここまで、BPクラスとの依存関係を切るために参照は抽象度の高いクラスへの参照としておくということを行ってきましたが、このままだとそのBPクラスの変数や関数にアクセスできません。
そこで使用するのがBPインターフェースです。
BPインターフェースはざっくり言うと「相手が誰であろうとやってほしいことを伝えて、あとは丸投げする」という機能です。
相手が具体的にどのクラスであるか知る必要がないので、抽象度の高いクラスへの参照さえ持っていればインターフェースを使用して欲しい情報にアクセスすることができます。
BPインターフェースではまず名前のみの関数、イベントを定義します。
そして具体的な実装はそのインターフェースを装備したクラス内でそれぞれ行います。
そして最後にインターフェースを送信します。このとき、Targetの型はなんでもよいので依存関係を切ったまま別のBPの情報にアクセスすることができます。
まとめ
複数人開発ならもちろんの事、個人開発でも依存関係を少なくする設計をすることによってバグを減らしたり、過去のコードについて思い出す必要が少なくなって開発効率がアップします!
是非みなさんもゲームを作る際には依存関係が少ない実装を心がけてみて下さい!