目次
※この記事で使用しているUnrealのVersionは04.24.1です。
※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト
参照渡し? レベル【★★】
皆さんが普段使っているBlueprintでのパラメーター(String,Intなど)のピンは配列や連想配列などを除けば、大体が丸い形をしていると思います。
しかし、まれに「Increment」や「Set Member in~~~」「Get(ref)」などのノードは、ピンがひし形をしている部分があります。
これは、そのパラメーターの参照、つまりそのパラメーターそのもののデータであるということです。
多分この説明では、わかっている人はわかっていて、わからない人はわからないままでしょう。
では簡単なテストを行います。
適当なBlueprint(ブログではLevelBP)を開きましょう。
→LevelBPは、Toolbar内の「Blueprints」から「Open Level Blueprint」を選択します。
Blueprint Editorを開けたら、「My Blueprint」ウィンドウ内の「Function」部分の右側の「+」を押し、新しい関数を作成します。
中身は以下のように組みます(TmpStringという新しいString型の変数を作成しました)
変数のデフォルト値は、小文字の「kinnaji」にし、関数内での「Set」で大文字の「KINNAJI」にしておきます。
この関数を、Event Graph上のBegin Playにつなげます。
そして、引数に作成したStringの変数のGetterを繋げます。
この状態でプレイインしてみましょう。
出力されるログは、小文字の「kinnaji」となるはずです。
では、一旦プレイをやめ、作成した関数のStringの引数を見てみます。
「Detail」内にある引数名の左に「▶」のマークがあると思いますので押してみましょう。
すると、引数のDefault Valueを設定する項目と「Pass-by-Reference」というチェックボックスがあると思います。
このチェックボックスにチェックを入れましょう。
すると、引数のStringピンがひし形になると思います。
この状態でもう一度プレイインを押してみましょう。
すると、今度は大文字の「KINNAJI」という文字が出力されると思います。
何が起きているのかを簡単に説明します。
通常の丸いピンの引数の場合は、String入力に入れた変数の値は直接関数に渡されません。
関数内に「ローカルな静的変数」が生成され、そこに引数の値が代入されます。
(つまりコピーされます)
それを、関数内で使用していることになります。
なので、この通常の丸いピンで渡すパラメーターを「コピーリファレンス」などと言ったりもします。
対して、ひし形ピンの方は、変数の値をコピーすることなく、変数そのものを使用しています。
お判りいただけましたでしょうか?
普段普通に関数に引数をつけている場合は、
内部ではローカル変数となって、関数内で使用されていることになります。
勘のいいお方ならお気づきかと思いますが、
通常の引数を使うよりも、参照渡しを使った方が処理は早いです。
実際に試してみましょう。
コピー渡しと参照渡しの処理速度の違いを検証 レベル【★★】
以下のような2つの処理を書いてみました。
どちらも、Blueprint関数部分以外は全く同じ処理を行います。
ちなみに関数内は空っぽです。
これをどちらの処理も10回程度実行し試してみました。
微々たる違いですが、参照をそのまま使う方が、コピーを作るよりも早いという結果になりました。
もう一つ実験。
どちらも10万回String配列から0番目の要素を取得して、それを変数に代入する、というものです。
違うのは、要素を取得する「Get」ノードの返り値がコピーか参照かという部分です。
結果↓↓
こちらは、まあまあの差が出てくれました。
このように、参照渡しをすることで、いくらか処理速度を上げることができました。
※注意
しかし、処理が速くなるからと言って、何も考えずにすべての関数の引数を参照渡しにしたりするのはよくないと思います。
参照を渡すということは、その値がどこで上書きされるかわからないので、処理を追いづらくしてしまいます。
逆に参照にしてしまったことにより、変数の中身が変わったタイミングで処理が変わってしまいバグを生むことにもなりかねません。
しっかりと設計から考えて使用していきましょう。
以上となります。
※検証時のPCスペックは
・CPU
Intel Core i7 2700K
・GPU
GeForce RTX 2060
です。
関連記事
リファレンス渡しに設定した時の動作(マクロ・イベント・関数の場合)
※この記事のサンプルプロジェクトは以下URLにアップされています。
サンプルプロジェクト