【UE4】C++でExecuteConsoleCommand実行関数ライブラリBP作ってみた
目次
- 目次
- C++で書こうと思ったきっかけ
- C++(UE4)は友達! 怖くないよ!
- staticでselfピンを無くす
- ExecuteConsoleCommandはどこにある?
- WorldContextObjectとは
- メタデータ指定子
- 出来た!
C++で書こうと思ったきっかけ
UE4 のブループリントしばらく使った後にC++ソースコードを書いた時「楽っ!軽っ!早っ!」ってなる。プログラム構築の速さと書きやすさで。BPは便利だけど「ちょっとした計算やプログラム」という場合においてはむしろ時間リソースを食う。エディタが重くなったらなおさら時間かかる#UE4
— 空母に似た形の艦船 イセミト (@isemito_niko) 2017年12月12日
つまるところ↑ツイートの通りなのですが、おおまかな処理等を構築する時にはBPは非常に有効です。しかし計算やループ(forではなく値の)処理を構築する場合はBPだと時間がかかる上に、見た目ブロック状のものが画面いっぱいになりそれらを繋ぐ線で埋まるので管理が難しくなってしまいます。
そして今回の場合はExecuteConsoleCommandをC++で実行させたいと思いました。
というのも、ExecuteConsoleCommandでゲームのクオリティ設定を行いたかったのですが、設定分ExecuteConsoleCommandノードがどんどん伸びていき、線も増えていき、コマンドの管理も時間がかかり始めていた、という背景があります。
というわけで書いてみました。ちなみにUE4でのC++は初です。
C++(UE4)は友達! 怖くないよ!
ガッ
というわけでいきなり噛みつかれました。
まず、当たり前といえば当たり前ですが初見でUE4での書き方が全くわからない。
とりあえず関数ライブラリを作り、Blueprint Function Libraryを親としてC++ファイルを作成
開いてみると...
[SystemFunctionLibrary.h]
[CalcFunctionLibrary.cpp]
ギリギリギリ...
色々調べてみてこちらの記事が見つかりましたので参考に進めていきます。
staticでselfピンを無くす
静的になるので当然ですが、staticにするとselfピンがなくなり、オブジェクトを渡す必要がなくなります。
例えば、
こう記述すれば...
「◯- ターゲット[self]」というピンが表示されますが、
こう記述すれば、
selfピンが消えます。
おっじゃあstatic付けてExecuteConsoleCommand実行するC++コードを書けば良いんだなと思い検索かけてみた所、
このポストにて
こう記述すれば実行できるよ! という情報がありました。
これでC++で ExecuteConsoleCommandを実行しましょう。
怖くない...怖くない...
ガッ
まだ駄目です。
なぜなら、
「GetWorld()」はconst修飾であり、sttaic関数内で使用できません。
「 じゃあconst付ければ使える..?」
と思いきやそうするともちろんstaticは外さなければならず故にselfピンが表示されてしまいます。
ExecuteConsoleCommandはどこにある?
ここで、そもそもExecuteConsoleCommandはどのソースコードにあるのか?
それを参考に書けば良いのではないか?
自力で探してみたものの見つからなかったのでAnswerHubにて質問した所、
ExecuteConsoleCommandと同等の機能をC++で実装したい - UE4 AnswerHub
「KismetSystemLibrary.h」にありました。
...あれ?
書いてあったああああああああああ!!!!
なるほど。
ともあれ、これでExecuteConsoleCommandを直接呼び出すことが可能になりました。
WorldContextObjectとは
ExecuteConsoleCommandを直接呼び出す方法はわかりましたが、今度は見覚えのない言葉が出てきました。
WorldContextObjectとは一体?
まず、WorldContextObjectの型はUObjectであり、これはUE4内全てのオブジェクトの親クラスになるものです。そして、
[C++] WorldContextObject Parameter - UE4 AnswerHub
にて回答者様がおっしゃっているとおり、WorldContectObjectはつまり「GetWorld()」を持つオブジェクトを指す。つまりWorldContectObject(UObject)経由で「GetWorld()」を呼び出しているということになるようです。
そしてExecuteConsoleCommandは渡されたWorldContextObjectからPlayerControllerを取得し、ConsoleCommandを実行しています。
[ExecuteConsoleCommand関数 中身]
メタデータ指定子
では、肝心のWorldContextObjectにはどうやって値を渡せば良いのか?
それは、「メタデータ指定子(meta)」と呼ばれるものを使用します。
上サイト内の「関数メタデータ指定子」に
WorldContext="Parameter"
BlueprintCallable 関数によって使用され、オペレーションが起こるワールドをどのパラメータが決めるかを示します。
という説明があります。
つまりこの場合「どのパラメータが決めるか」というのは「WorldContextObject」であり、故に「"Parameter"」の箇所には「WorldContextObject」を割り当てます。そうすることで、オペレーションが起こるワールドはWorldContextObjectが持つことを示すことになるのかもしれません(勉強不足でまだ完全には理解できていません)。
出来た!
ともあれ、これでstaticしつつExecuteConsoleCommandを呼び出すことが出来るようになりました。
最終的なコードは以下になります。
最初に述べたとおりゲームのクオリティ設定が元々の目的だったのでクオリティ設定のコードになっています。
[SystemFunctionLibrary.h]
[SystemFunctionLibrary.cpp]