6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[UE5](C++)自作Curveクラスを作成してカーブエディターで利用する

Posted at

確認UE5: 5.4.4

image.png
グラフベースでタイムライン等の制御に利用できる便利なCurveVector、CurveLinearColor。

運用していると、下記のようになる事が偶にあります。ありました。

  • CurveVectorではカーブが3つ。今回5つのパラメーターがあるので CurveVector を2つ使います
    • 1つのカーブアセットで編集したい……アセット切り替えたくない……
  • X は "Intensity"、Y は "Attenuation" として内部的には扱います
    • "X, Y, Z" ではなくて、実際のパラメーターの名前にしたい……どれがどれだっけ、になる……

このような場合に、Curveアセットの種類を自作していい感じにします

image.png
このような形で、上図はカーブを6つ用意、それぞれに名前を設定して分かりやすくしています。

実装コード

C++で UCurveBase を継承するだけで利用可能です。

PostProcessCurve.h
UCLASS()
class UPostProcessCurve : public UCurveBase
{
	GENERATED_UCLASS_BODY()

	UPROPERTY()
	FRichCurve FloatCurves[6]; // todo 要素番号を定数化

	UFUNCTION(BlueprintCallable, Category="Math|Curves")
	float GetValue(int32 CurveIndex, float InTime) const;


	// Begin FCurveOwnerInterface
	virtual TArray<FRichCurveEditInfoConst> GetCurves() const override;
	virtual TArray<FRichCurveEditInfo> GetCurves() override;
	virtual FLinearColor GetCurveColor(FRichCurveEditInfo CurveInfo) const override;
	virtual bool IsValidCurve( FRichCurveEditInfo CurveInfo ) override;

	bool operator == (const UPostProcessCurve& Curve) const;
};
PostProcessCurve.cpp
UPostProcessCurve::UPostProcessCurve(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
#if WITH_EDITOR
	// カーブの初期値を設定したい場合に
	bool bIsEmpty = true;
	for (int32 Index = 0 ; Index < UE_ARRAY_COUNT(FloatCurves) ; ++Index)
	{
		if (FloatCurves[Index].GetNumKeys() > 0)
		{
			bIsEmpty = false;
			break;
		}
	}
	if (bIsEmpty)
	{
		FloatCurves[0].AddKey(0.0f, 6500.0f);
		FloatCurves[1].AddKey(0.0f, 0.5f);
		FloatCurves[2].AddKey(0.0f, 1.0f);
		FloatCurves[3].AddKey(0.0f, 0.0f);
		FloatCurves[4].AddKey(0.0f, 0.0f);
		FloatCurves[5].AddKey(0.0f, 0.0f);
	}
#endif
}

float UPostProcessCurve::GetValue(int32 CurveIndex, float InTime) const
{
	if ((CurveIndex < 0) || (CurveIndex >= UE_ARRAY_COUNT(FloatCurves)))
	{
		ensure(false);
		return 0;
	}
	return FloatCurves[CurveIndex].Eval(InTime);
}

// カーブエディターで表示される名前
static const FName PostProcessCurveWhiteTempName(TEXT("WhiteTemp"));
static const FName PostProcessCurveBloomName(TEXT("Bloom"));
static const FName PostProcessCurveLensFlareName(TEXT("LensFlare"));
static const FName PostProcessCurveVignetteName(TEXT("Vignette"));
static const FName PostProcessCurveFringeName(TEXT("Fringe"));
static const FName PostProcessCurveMotionBlurName(TEXT("MotionBlur"));

TArray<FRichCurveEditInfoConst> UPostProcessCurve::GetCurves() const
{
	TArray<FRichCurveEditInfoConst> Curves;
	Curves.Add(FRichCurveEditInfoConst(&FloatCurves[0], PostProcessCurveWhiteTempName));
	Curves.Add(FRichCurveEditInfoConst(&FloatCurves[1], PostProcessCurveBloomName));
	Curves.Add(FRichCurveEditInfoConst(&FloatCurves[2], PostProcessCurveLensFlareName));
	Curves.Add(FRichCurveEditInfoConst(&FloatCurves[3], PostProcessCurveVignetteName));
	Curves.Add(FRichCurveEditInfoConst(&FloatCurves[4], PostProcessCurveFringeName));
	Curves.Add(FRichCurveEditInfoConst(&FloatCurves[5], PostProcessCurveMotionBlurName));
	return Curves;
}

TArray<FRichCurveEditInfo> UPostProcessCurve::GetCurves()
{
	TArray<FRichCurveEditInfo> Curves;
	Curves.Add(FRichCurveEditInfo(&FloatCurves[0], PostProcessCurveWhiteTempName));
	Curves.Add(FRichCurveEditInfo(&FloatCurves[1], PostProcessCurveBloomName));
	Curves.Add(FRichCurveEditInfo(&FloatCurves[2], PostProcessCurveLensFlareName));
	Curves.Add(FRichCurveEditInfo(&FloatCurves[3], PostProcessCurveVignetteName));
	Curves.Add(FRichCurveEditInfo(&FloatCurves[4], PostProcessCurveFringeName));
	Curves.Add(FRichCurveEditInfo(&FloatCurves[5], PostProcessCurveMotionBlurName));
	return Curves;
}
FLinearColor UPostProcessCurve::GetCurveColor(FRichCurveEditInfo CurveInfo) const
{
	// カーブエディターで表示される色
	if (CurveInfo.CurveName == PostProcessCurveWhiteTempName)       return FLinearColor(0.8f, 0.2f, 0.2f);
	else if (CurveInfo.CurveName == PostProcessCurveBloomName)      return FLinearColor(0.8f, 0.8f, 0.2f);
	else if (CurveInfo.CurveName == PostProcessCurveLensFlareName)  return FLinearColor(0.2f, 0.8f, 0.2f);
	else if (CurveInfo.CurveName == PostProcessCurveVignetteName)   return FLinearColor(0.2f, 0.8f, 0.8f);
	else if (CurveInfo.CurveName == PostProcessCurveFringeName)     return FLinearColor(0.2f, 0.2f, 0.8f);
	else if (CurveInfo.CurveName == PostProcessCurveMotionBlurName) return FLinearColor(0.8f, 0.2f, 0.8f);

	return Super::GetCurveColor(CurveInfo);
}

bool UPostProcessCurve::IsValidCurve( FRichCurveEditInfo CurveInfo )
{
	for (const auto& Curve : FloatCurves)
	{
		if (CurveInfo.CurveToEdit == &Curve)
		{
			return true;
		}
	}
	return false;
}

bool UPostProcessCurve::operator == (const UPostProcessCurve& Curve) const
{
	for (int32 Index = 0 ; Index < UE_ARRAY_COUNT(FloatCurves) ; ++Index)
	{
		if (Curve.FloatCurves[Index] != FloatCurves[Index])
		{
			return false;
		}
	}
	return true;
}

上記のように UCurveBaseを継承したクラスを用意すると、Editorでのカーブアセット作成時にクラスが表示されて使用可能になります。
image.png

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?