UE5 では、==
や +
などの演算が、ワイルドカードで扱えるようになっています
TypePromotion
という機能なのですが、今回はそれにまつわることを紹介します
TypePromotion とは? #
特定のルールに従って、演算子ノードを 1 つのワイルドカード演算子として扱う機能です
UE4 から使っている人にとってはめんどくさいのですが、どの計算でも Equal
、 Add
、Subtract
など、共通の言葉で検索できるので、ノード検索上はそれなりに便利な機能です
TypePromotion を自作の構造体で使用する #
TypePromotion のルールは簡単です
- C++の Static 関数であること
- 特定の Prefix を持っていること
特定の Prefix とは以下のとおりです
演算子 | Prefix | 備考 |
---|---|---|
== | EqualEqual_ | 等しい |
!= | NotEqual_ | 等しくない |
+ | Add_ | 加算 |
* | Multiply_ | 乗算 |
- | Subtract_ | 減算 |
/ | Divide_ | 除算 |
> | Greater_ | より大きい |
>= | GreaterEqual_ | 以上 |
< | Less_ | より小さい |
<= | LessEqual_ | 以下 |
大体は BlueprintFunctionLibrary にまとめることになるかと思います
なお、BP では対応できません
実装例 #
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"
USTRUCT(BlueprintType)
struct FMyComparableStruct {
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 Value;
public:
inline bool operator==(const FMyComparableStruct& Othrer) const
{
return Value == Othrer.Value;
}
};
/**
*
*/
UCLASS()
class CPPWORLD51_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, Category="MyStruct", meta=(DisplayName = "Equal (MyStruct)", CompactNodeTitle = "==", Keywords = "== equal"))
static bool EqualEqual_MyStruct(const FMyComparableStruct& A, const FMyComparableStruct& B)
{
return A == B;
}
};
既知の問題点 #
実はこの TypePromotion、いくつか問題を抱えています
DateTime 型の計算ができない #
DateTime 型( FDateTime
)ももちろん TypePromotion に対応した作りになっています
なので対応しているはず…なのですが
実は DateTime 型が関わる計算はパターンが多く、ワイルドカードが正しく判別できないという問題を抱えています
具体的なパターンは以下のとおりです
- FDateTime - FDatetime ( = FTimespan )
- FDatetime - FTimespan ( = FDateTime )
- FTimespan - FTimespan ( = FTimespan )
TypePromotion はワイルドカードの入力か出力を見て判断するんですが
DateTime と Timespan に関しては 1 つが決まってももう 1 つ決まらないと確定できない、という状態になっています
おそらく判別はきちんと出来てるような気がしますが、
- A に DateTime が接続される
- ReturnValue が FTimeSpan になる
- A,B が ReturnValue と同じ型のものが優先されるので、(Timespan - Timespan) に自動的に変更される
- DateTime と Timespan では型が合わないので接続できなくなる
みたいなことが起きているように思います
なので、 Subtract
で (DateTime - DateTime) をして経過時間を出そうとしても、型が合わず接続できない、という状況になっています
おそらくこれはすぐ直らない気がします
違う型の場合のリテラル値が面倒 #
UE4 から使ってる人にとってはわりとめんどくさいのがこれかと思います
UE4 では (Vector _ float) とかが 1 回で出せたのですが、UE5 では Multiple
を使うと (Vector _ Vector) が優先されます
float に変更しようとしたら、ピンを右クリックしてワイルドカードの変更をしないといけません
めんどくさくて Make Literal Float
を差してなんとかしている人も多いんじゃないでしょうか
TypePromotion を無効にする #
実は UE4 時代と同じ動作に戻すことができます
EditorPreference の General - BlueprintEditorSettings
にある General > Enable Type Promotion
を OFF にすると、ワイルドカードではなく UE4 のときと同じ、個別の演算子ノードが選べるようになります