UE4C++UI平滑曲线图绘制

UE4C++UI平滑曲线图绘制

  • 前言
    UE4的曲线在UMG上面绘制的时候总是和麻烦的,这里我们借用UE4曲线FRichCurve,向其中传入对应的Key值,然后差值获取俩个点之间的数据,然后将所有点连接则是对应的平滑曲线。(此处没计算,用的FRichCurve中所自带点的计算),逻辑比较简单,在此不过多赘述。

需要添加模块: "SlateCore", "UMG"才能编译成功

附源码:

  • .h文件
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "SmoothedLineWidget.generated.h"

/**
 *
 */
UCLASS()
class SPECIALCHART_API USmoothedLineWidget : public UUserWidget
{
	GENERATED_BODY()

public:
	USmoothedLineWidget(const FObjectInitializer& ObjectInitializer);
	
	UFUNCTION(BlueprintCallable)
		void SetValues(TArray<float> InValues);//计算对应的key值,默认在绘制前已调用
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		FVector2D Size= FVector2D(100,100);//大小
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		FVector2D Locationn = FVector2D(100, 100);//位置
	UPROPERTY(EditAnywhere,BlueprintReadWrite)
		float BrushSize=5;//笔刷大小
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		FColor Color;//颜色
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		TArray<float> Values;//传入的线对应的值
	virtual void NativePreConstruct() override;
protected:
	virtual int32 NativePaint(
		const FPaintArgs& Args,
		const FGeometry& AllottedGeometry,
		const FSlateRect& MyCullingRect,
		FSlateWindowElementList& OutDrawElements,
		int32 LayerId,
		const FWidgetStyle& InWidgetStyle,
		bool bParentEnabled) const override;//绘制函数

private:
	void DrawSmoothedLine(
		FSlateWindowElementList& OutDrawElement,
		int InLayerId,
		const FGeometry& InAllottedGeometry,
		TArray<FVector2D> InPoints,
		float InThickness,
		FColor InColor
	)const;//线的绘制
	//线所包含的顶点
	TArray<FVector2D> MultiplyPoint;
};
  • .cpp文件
// Fill out your copyright notice in the Description page of Project Settings.


#include "SmoothedLineWidget.h"
#include "Components/CanvasPanelSlot.h"


USmoothedLineWidget::USmoothedLineWidget(const FObjectInitializer& ObjectInitializer)
	:Super(ObjectInitializer)
{
}

void USmoothedLineWidget::SetValues(TArray<float> InValues)
{
	if (InValues.Num() < 2)
		return;

	MultiplyPoint.Empty();

	float WidgetWidth = Size.X;
	float WidgetHeight = Size.Y;

	float Space = WidgetWidth / (InValues.Num() - 1);
	for (int32 Index = 0; Index < InValues.Num(); Index++)
	{
		FVector2D KeyPosition(Space * Index, WidgetHeight - InValues[Index]);
		MultiplyPoint.Add(KeyPosition);
	}
}

void USmoothedLineWidget::NativePreConstruct()
{
	Super::NativePreConstruct();
	SetValues(Values);
}

int32 USmoothedLineWidget::NativePaint(const FPaintArgs& Args,
                                       const FGeometry& AllottedGeometry,
                                       const FSlateRect& MyCullingRect,
                                       FSlateWindowElementList& OutDrawElements, 
                                       int32 LayerId,
                                       const FWidgetStyle& InWidgetStyle,
                                       bool bParentEnabled) const
{
	DrawSmoothedLine(
		OutDrawElements,
		LayerId,
		AllottedGeometry,
		MultiplyPoint,
		BrushSize,
		Color);
	return LayerId++;
}

void USmoothedLineWidget::DrawSmoothedLine(
	FSlateWindowElementList& OutDrawElement,
	int InLayerId,
	const FGeometry& InAllottedGeometry,
	TArray<FVector2D> InPoints,
	float InThickness,
	FColor InColor) const
{
	if (InPoints.Num() < 2)
		return;

	FRichCurve* RichCurve = new FRichCurve();

	for (FVector2D InPoint : InPoints)
	{
		FKeyHandle KeyHandle = RichCurve->AddKey(InPoint.X, InPoint.Y);
		RichCurve->SetKeyInterpMode(KeyHandle, ERichCurveInterpMode::RCIM_Cubic);
	}

	UCanvasPanelSlot* CanvsdPanelSlot = Cast<UCanvasPanelSlot>(this->Slot);


	TArray<FVector2D> ResultPoints;
	

	float WidgetWidth = Size.X;
	float WidgetHeight = Size.Y;
	int32 Begin = 0;
	int32 End = (int32)WidgetWidth;
	for (int32 X = Begin; X < End; X++)
	{
		float Y = RichCurve->Eval(X);
		FVector2D ResultPoint(X+ Locationn.X, Y+ Locationn.Y);
		ResultPoints.Add(ResultPoint);
	}

	delete RichCurve;

	FSlateDrawElement::MakeLines(
		OutDrawElement,
		InLayerId,
		InAllottedGeometry.ToPaintGeometry(),
		ResultPoints,
		ESlateDrawEffect::None,
		InColor,
		true,
		InThickness
	);
}

UE4C++UI平滑曲线图绘制_第1张图片

你可能感兴趣的:(UEC++,ue4,c++)