Featured image of post [UE5] 入力ピンに接続した変数を読み書きする BP 関数を作成する方法 (C++ で作成編) (UPARAM(ref))

[UE5] 入力ピンに接続した変数を読み書きする BP 関数を作成する方法 (C++ で作成編) (UPARAM(ref))

UE 5.1.1

結論

C++ で関数を定義する場合、非 const な参照型引数を用いて実装できます。ただし、普通に宣言すると出力ピンになってしまうので、関数宣言内の引数の直前に UPARAM(ref) を記述して、入力ピンにする必要があります。

1
2
3
4
5
UFUNCTION(BlueprintCallable)
static void IncrementIntTest(UPARAM(ref) int32& Arg)
{
    Arg = Arg + 1;
};

実例

前回の記事では、『入力ピンに接続した Integer 型変数をインクリメント (+ 1) する BP 関数』を Blueprint で作成しました。

今回は、同じものを C++ で作成します。

1
2
3
4
5
UFUNCTION(BlueprintCallable)
static void IncrementIntTest(int32& Arg)
{
    Arg = Arg + 1;
};

はい。C++er にとってはこんなの楽勝ですよね。

この関数、C++ では問題なく動作するのですが、Blueprint で呼び出してみると……

!?

Arg が出力ピンになってしまいました。これでは、変数を入力として接続することができません。

「参照型引数を入力ピンにする」というだけであれば、const を付ければ実現できるのですが……

1
2
3
4
5
UFUNCTION(BlueprintCallable)
static void IncrementIntTest(const int32& Arg)
{
    // Arg = Arg + 1;
}

当然、const 参照に対して値を代入することはできないので、コンパイルエラーになります。これでは本末転倒です。

このような場合は、入力ピンにしたい参照型引数の直前に UPARAM(ref) を記述します。

1
2
3
4
5
UFUNCTION(BlueprintCallable)
static void IncrementIntTest(UPARAM(ref) int32& Arg)
{
    Arg = Arg + 1;
};

これで、Arg が参照渡しの (菱形の) 入力ピンになります。

問題なく動作することを確認できました。

検証 : 値渡しの引数に UPARAM(ref) を付けるとどうなるか

実験してみます。

1
2
3
4
5
UFUNCTION(BlueprintCallable)
static void IncrementIntTest(UPARAM(REF) int32 Arg) // & を削除 (Arg を値渡しに変更)
{
    Arg = Arg + 1;
}

コンパイルが通ってしまいました。

Arg のピンの形は参照渡しを示す菱形になっており、変更前と見分けがつきません。

ですが、実際のところ Arg は値渡しなので、接続した変数はインクリメントされません。

つまり、誤って値渡しの引数に UPARAM(ref) を付けてしまうと、『ピンの見た目は参照渡し』なのに『実際の挙動は値渡し』という邪悪な Node が爆誕します。発見しにくいバグになるため、十分注意しましょう。

(´-`).。oO (これに関しては Unreal Header Tool がエラーを吐いてほしいなぁ……)

(´-`).。oO (おわり)

参考