メインコンテンツへスキップ
  1. 記事/

TypePromotionについての考察

UnrealEngine UE5.1 TypePromotion C++ Blueprint

UE5 では、== や + などの演算が、ワイルドカードで扱えるようになっています
TypePromotion という機能なのですが、今回はそれにまつわることを紹介します

TypePromotion とは? #

特定のルールに従って、演算子ノードを 1 つのワイルドカード演算子として扱う機能です
UE4 から使っている人にとってはめんどくさいのですが、どの計算でも EqualAddSubtract など、共通の言葉で検索できるので、ノード検索上はそれなりに便利な機能です

TypePromotion を自作の構造体で使用する #

TypePromotion のルールは簡単です

  • C++の Static 関数であること
  • 特定の Prefix を持っていること

特定の Prefix とは以下のとおりです

演算子 Prefix 備考
== EqualEqual_ 等しい
!= NotEqual_ 等しくない
+ Add_ 加算
* Multiply_ 乗算
- Subtract_ 減算
/ Divide_ 除算
> Greater_ より大きい
>= GreaterEqual_ 以上
< Less_ より小さい
<= LessEqual_ 以下

大体は BlueprintFunctionLibrary にまとめることになるかと思います

なお、BP では対応できません

実装例 #

Alt text

#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 つ決まらないと確定できない、という状態になっています

おそらく判別はきちんと出来てるような気がしますが、

  1. A に DateTime が接続される
  2. ReturnValue が FTimeSpan になる
  3. A,B が ReturnValue と同じ型のものが優先されるので、(Timespan - Timespan) に自動的に変更される
  4. DateTime と Timespan では型が合わないので接続できなくなる

みたいなことが起きているように思います

なので、 Subtract で (DateTime - DateTime) をして経過時間を出そうとしても、型が合わず接続できない、という状況になっています
おそらくこれはすぐ直らない気がします

違う型の場合のリテラル値が面倒 #

UE4 から使ってる人にとってはわりとめんどくさいのがこれかと思います
UE4 では (Vector _ float) とかが 1 回で出せたのですが、UE5 では Multiple を使うと (Vector _ Vector) が優先されます
float に変更しようとしたら、ピンを右クリックしてワイルドカードの変更をしないといけません

Change Wildcard

めんどくさくて Make Literal Float を差してなんとかしている人も多いんじゃないでしょうか

Make Literal Float

TypePromotion を無効にする #

実は UE4 時代と同じ動作に戻すことができます

EditorPreference の General - BlueprintEditorSettings にある General > Enable Type Promotion を OFF にすると、ワイルドカードではなく UE4 のときと同じ、個別の演算子ノードが選べるようになります

UE4Style

Related

BPでn次元配列を扱う
UnrealEngine Blueprint UE5.2
Android(Meta Quest2)でUnrealInsightを使う
UnrealEngine UE5.1 Mobile Android VR
C++プロジェクトがビルドできないときはパスをチェックする
UnrealEngine UE5.0 C++