饼状图
- 使用UE绘制前提
- 完整的创建过程
- 1
- 2
- 3
- 4
- 5
- 6
- 6
- 7
- 8
- 附录代码
- .h代码
- .c代码
使用UE绘制前提
EPIC Game使用的版本是Unreal Engine 5.0.3。
没有使用其他额外的插件,使用的是C++和Ui共同绘制。
C++编译器使用的是VS2019。
完整的创建过程
1
首先在UE中随意一种项目的白色。默认为C++,名称注意使用英文
2
3
4
之后就直接跳进VS2019中去了。然后将附录中的代码整上去。先保存后编译。一定要先保存后编译
上面的报错全都无伤大雅,真正的检查是在Live Coding 中。
但是如果有其他的报错还是要研究分析一下,比如中英文错了等等。不再多提。
5
完成VS2019中的编码后使用的检测系统如下图所示,快捷键是Ctrl + Alt + F11。
如果Live Coding中显示Successfully,那么就成功了
6
在进入到UE中新建一个UI控件
6
7
控件蓝图中放入画布画板,再将你自己命名的用户控件放入其中
8
在右上角点击转移到图表中去,然后连线如下
运行后如下
也可以进行更改,让他显示两个饼图
颜色大小都可以自定义来实现。
附录代码
.h代码
.h文件代码如下
// Fill out your copyright notice in the Description page of Project Settings.#pragma once
#include <fstream>
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "PieWidget.generated.h"/*** */
UCLASS()
class ECHART1_API UPieWidget : public UUserWidget
{GENERATED_BODY()public:UFUNCTION(BlueprintCallable)void SetValues(TArray<float> InValues);UFUNCTION(BlueprintCallable)void SetColor(TArray<FLinearColor> InColors);
protected:virtual int32 NativePaint(const FPaintArgs& Args,const FGeometry& AllottedGeometry,const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId,const FWidgetStyle& InWidgetStyle,bool bParentEnabled) const;
private://私有的绘制扇形所需元素从上到下依次是//绘制所需元素,绘制所需几何,所需元素,圆心所在,半径,圆心开始角度,结束角度,颜色void DrawFan(FSlateWindowElementList& OutDrawElements,const FGeometry& AllottedGeometry,int32 Layer,const FVector2D& CenterPosition,float Radius,int32 BeginAngle,int32 EndAngle,FColor Color)const;TArray<int32> Angles;TArray<FLinearColor> Colors;FColor GetColorByIndex(int32 InIndex)const;
};
.c代码
.c文件如下
#include "PieWidget.h"void UPieWidget::SetValues(TArray<float> InValues)
{if (InValues.Num() < 1)return;Angles.Empty();Angles.Add(0);//求取数据的总值float Total = 0;for (int32 Index = 0; Index < InValues.Num(); Index++){Total += InValues[Index];}//求取每个值占总值的多少,化成度数float CurrentTotal = 0;for (int32 Index = 0; Index < InValues.Num(); Index++){CurrentTotal += InValues[Index];int32 Angle = (int32)((CurrentTotal / Total) * 360);Angles.Add(Angle);}
}void UPieWidget::SetColor(TArray<FLinearColor> InColors)
{Colors = InColors;
}int32 UPieWidget::NativePaint(const FPaintArgs& Args,const FGeometry& AllottedGeometry,const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId,const FWidgetStyle& InWidgetStyle,bool bParentEnabled) const
{//绘制饼状图for (int32 Index = 0; Index < Angles.Num() - 1; Index++){int32 BegingAngle = Angles[Index];int32 EndAngle = Angles[Index + 1];DrawFan(OutDrawElements, AllottedGeometry, LayerId, FVector2D(300.f, 300.f), 250.f, BegingAngle, EndAngle, GetColorByIndex(Index));}return LayerId++;
}void UPieWidget::DrawFan(FSlateWindowElementList& OutDrawElements, const FGeometry& AllottedGeometry, int32 Layer, const FVector2D& CenterPosition, float Radius, int32 BeginAngle, int32 EndAngle, FColor Color) const
{//绘制扇形if (EndAngle <= BeginAngle)//如果结束角度小于等于开始角度,不用绘制return;if (Radius <= 0.f)//半径很小也不绘制return;//定义顶点数组TArray<FSlateVertex> SlateVertexArray;//定义索引数组TArray<SlateIndex> SlateIndexArray;//画三角for (int32 CurrentAngle = BeginAngle; CurrentAngle < EndAngle; CurrentAngle++){FSlateVertex CurrentSlateVertex;//当前顶点FSlateVertex NextSlateVertex;//下一个顶点FSlateVertex CenterSlateVertex;//中心点//将当前顶点的一维转换为二维FVector2D CurrentSlateVertextPositon = FVector2D(CenterPosition.X + Radius * FMath::Cos(FMath::DegreesToRadians(CurrentAngle)),CenterPosition.Y + Radius * FMath::Sin(FMath::DegreesToRadians(CurrentAngle)));//将下一个顶点的一维转换为二维FVector2D NextSlateVertextPositon = FVector2D(CenterPosition.X + Radius * FMath::Cos(FMath::DegreesToRadians(CurrentAngle + 1)),CenterPosition.Y + Radius * FMath::Sin(FMath::DegreesToRadians(CurrentAngle + 1)));//位置赋给三个顶点CurrentSlateVertex.Position = (FVector2f)AllottedGeometry.ToPaintGeometry().GetAccumulatedRenderTransform().TransformPoint(CurrentSlateVertextPositon);NextSlateVertex.Position = (FVector2f)AllottedGeometry.ToPaintGeometry().GetAccumulatedRenderTransform().TransformPoint(NextSlateVertextPositon);CenterSlateVertex.Position = (FVector2f)AllottedGeometry.ToPaintGeometry().GetAccumulatedRenderTransform().TransformPoint(CenterPosition);CurrentSlateVertex.Color = Color;NextSlateVertex.Color = Color;CenterSlateVertex.Color = Color;//把三个坐标放入到数组中int32 IndexOfCurrentSlateVertex = SlateVertexArray.Add(CurrentSlateVertex);int32 IndexOfNextSlateVertex = SlateVertexArray.Add(NextSlateVertex);int32 IndexOfCenterSlateVertex = SlateVertexArray.Add(CenterSlateVertex);//把索引值放入到索引数组中SlateIndexArray.Add(IndexOfCurrentSlateVertex);SlateIndexArray.Add(IndexOfCenterSlateVertex);SlateIndexArray.Add(IndexOfNextSlateVertex);}//顶点的UVfor (FSlateVertex& TempSlateVertex : SlateVertexArray){TempSlateVertex.TexCoords[0] = 0.0f;TempSlateVertex.TexCoords[1] = 0.0f;TempSlateVertex.TexCoords[2] = 0.0f;TempSlateVertex.TexCoords[3] = 0.0f;}//绘制const FSlateBrush* SlateBrush = FCoreStyle::Get().GetBrush("ColorSpectrum.Spectrum");FSlateResourceHandle SlateResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(*SlateBrush);FSlateDrawElement::MakeCustomVerts(OutDrawElements,Layer,SlateResourceHandle,SlateVertexArray,SlateIndexArray,nullptr, 0, 0);
}FColor UPieWidget::GetColorByIndex(int32 InIndex) const
{if (Colors.Num() < 1)return FColor::White;return Colors[InIndex % Colors.Num()].ToFColor(true);
}