UE4 C++OnPain函数的用法

摘要:
本文主要介绍在C++中如何使用OnPaint函数去每帧的绘画文字,图片,线段,或者是其他的控件。
该功能一般使用的场景是用于小地图, 或者是其他的需要动态变化的UI界面,特别是当需要动态的去增加,删除各种控件的时候,一般都是用Onpaint函数去画出来。 该功能的实现主要是用Scompoundwidget类中的OnPaint函数去实现的,只要给一系列参数。

具体实现
一.创建一个SlateWidgetStyle,和一个普通的C++类,我们通过这个单例C++类来获取SlateWidgetStyle,这样可以避免SlateWidgetStyle重复注册,或者重复卸载。下面是普通C++类的实现,主要要代码是Create()函数通过路径去获取到引擎中的Style,接下来只要在主模块加载和卸载的时候分别去调用Initialze(),Shutdown()就可以了。然后去引擎中/Game/Widget/路径创建我们建立的SlateWidgetStyle并且命名为MySlate.

TSharedPtr<FSlateStyleSet>Slogin::StyleInstance = NULL;

void Slogin::Initialze()
{
	if (!StyleInstance.IsValid())
	{
		StyleInstance = Create();
		//把从编辑器中拿到的Style注册到FSlateStyleRegistry
		FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance);
	}
}

FName Slogin::GetStyleSetName()
{
	//随便给FSlateStyleName命一个名字
	static FName SlateSetName(TEXT("juso do"));
	return SlateSetName;
}

void Slogin::Shutdown()
{
       //取消注册
	FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance);
	ensure(StyleInstance.IsUnique());
	StyleInstance.Reset();
}



const ISlateStyle& Slogin::Get()
{
	return *StyleInstance;
}




TSharedRef<class FSlateStyleSet> Slogin::Create()
{
	//根据系统路径获取SlateSyeleSet并且重新命名为GetStyleSetName返回的名字
TSharedRef<FSlateStyleSet> styleRef = FSlateGameResources::New(Slogin::GetStyleSetName(), 	"/Game/Widget/MySlate", "/Game/Widget/MySlate");
	return styleRef;
}

二.在创建的SlateWidgetStyle中我们只要在.h文件写入我们需要的图片或者字体就可以了, 注意要写在.h文件中的第一个结构体下。
在这里插入图片描述
三.在新建一个SlateWidget,我们具体的绘制方法就在这里实现,利用重写的OnPaint()函数来绘制出我们需要的效果。具体实现代码如下。

注意具体使用从这里开始看就可以了。

int32 SMyDrawWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	SCompoundWidget::OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);


	//绘制文字
	FSlateDrawElement::MakeText(
		OutDrawElements,
		LayerId + 10,
		AllottedGeometry.ToPaintGeometry(FVector2D(50, 50), FVector2D(50,50)),
		NSLOCTEXT("SlAiGame", "这个一个测试", "这个一个测试"),
		Style->TextFont,//这里是一个上面定义的FSlateFontInfo
		ESlateDrawEffect::None,
		FLinearColor(1, 1, 1, 1)
	);

        //绘制文字
	FSlateDrawElement::MakeText(
		OutDrawElements,
		LayerId + 10,
		AllottedGeometry.ToPaintGeometry(FVector2D(960, 540), FVector2D(500, 500),1),
		NSLOCTEXT("SlAiGame", "N", "N"),
		Style->TextFont, //这里是一个上面定义的FSlateFontInfo
		ESlateDrawEffect::None,
		FLinearColor(1, 1, 1, 1)
	);
             //绘制图片
		FSlateDrawElement::MakeBox(
			OutDrawElements,
			LayerId + 10,
			AllottedGeometry.ToPaintGeometry(FVector2D(100, 100), FVector2D(50, 50)),
			&Style->DrawBrushOne,//这里是一个上面定义的FSlateBrush
			ESlateDrawEffect::None,
			FLinearColor(1, 0, 0, 1)
		);
	
	

	return LayerId;
}

这里我们具体来讨论OnPaint函数所需要的参数和他们都是拿来干什么的,我们先看绘制文字的

FSlateDrawElement::MakeText(
		OutDrawElements,
		LayerId + 10,
		AllottedGeometry.ToPaintGeometry(FVector2D(960, 540), FVector2D(500, 500),1),
		NSLOCTEXT("SlAiGame", "N", "N"),
		Style->TextFont,
		ESlateDrawEffect::None,
		FLinearColor(1, 1, 1, 1));

OutDrawElements,是需要绘画元素的列表,我们当前Make出来的Text,或者Image,或者什么其他的控件都会加入这个列表让这个函数去帮忙绘制。

LayerId, 是绘画当前元素的层级,当两个元素绘画在同一位置上的时候, 低层级的元素会被高层级的元素遮挡住。

AllottedGeometry,是当前元素的几何变化,关于坐标的转换一般都是利用它来实现的,我们调用它里面的ToPaintGeometry()来选择绘制元素的位置和大小,第一个Fvector2D传入的是LocalOffset,可以将其理解成是元素在屏幕中的位置,第二个FVctor2D传入的是当前绘制元素的大小,最后一个参数传入的是一个float类型的值,它表示当把窗口的缩放到当前值的时候,元素所在屏幕中的位置,后面无论窗口怎么缩放,绘画元素都会按最开始的比例显示在窗口上。

NSLOCTEXT(“SlAiGame”, “N”, “N”),一个本地化文字, 这就是你自己需要绘制的文字, 写什么都可以。
Style->TextFont, 这里给的是一个FslateFont就是字体的样式,其中Style是我在.h文件中声明的
const struct FMySlateStyle* Style; 它的赋值是在构造函数里面
Style = &Slogin::Get().GetWidgetStyle(“MySlate”);通过最开始写的单例去获取样式,这就就可以在编辑器中修改了。

ESlateDrawEffect::None, 这个是绘制元素的可以添加的效果,一般选择None就完全够用了。

FLinearColor(1, 1, 1, 1), 最后一个是绘制这个元素的前景色,可以改变字体的颜色。

以上就是绘制字体的时候所要填入的参数,当绘制图片的时候只需要一点小小的变化如下:

FSlateDrawElement::MakeBox(
			OutDrawElements,
			LayerId + 10,
			AllottedGeometry.ToPaintGeometry(FVector2D(x, 100), FVector2D(50, 50)),
			&Style->DrawBrushOne,
			ESlateDrawEffect::None,
			FLinearColor(1, 0, 0, 1));

前三个参数和最后两个参数同绘制字体的时候是一模一样的,不一样的是第四个参数, 它传入的是一个FslateBrush,就是所要绘制的图片。

四.效果展示
配置一个图片和一个字体样式

在C#中,你可以使用Windows Presentation Foundation (WPF) 或者Graphics类来进行图形绘制。这里是一个简单的示例,使用WPF的Canvas和Path元素来创建这个场景: ```csharp using System.Windows; using System.Windows.Controls; using System.Windows.Media; public partial class DrawingPage : Page { public DrawingPage() { InitializeComponent(); Canvas canvas = new Canvas(); canvas.Width = 500; // 设置Canvas宽度 canvas.Height = 500; // 设置Canvas高度 // 创建外圆 Path outerCircle = new Path(); outerCircle.Stroke = Brushes.Black; // 设置边框颜色 outerCircle.StrokeThickness = 2; // 边框宽度 outerCircle.Fill = Brushes.Gray; // 内填充色 outerCircle.Data = new EllipseGeometry(250, 250, 200); // 半径为100的圆形,中心点(250, 250) canvas.Children.Add(outerCircle); // 创建内圆 Path innerCircle = new Path(); innerCircle.Stroke = Brushes.Red; innerCircle.StrokeThickness = 1; innerCircle.Fill = Brushes.White; innerCircle.Data = new EllipseGeometry(250, 250, 100); canvas.Children.Add(innerCircle); // 创建内圆中心的直线 Line line = new Line(); line.X1 = 250; // 内圆中心X坐标 line.Y1 = 250 - 50; // 内圆中心Y坐标减去半径的一半(因为要在内圆中心画) line.X2 = 250 + 100; // 直线终点X坐标等于外圆半径加中心点X坐标 line.Y2 = 250 + 100; line.Stroke = Brushes.Blue; line.StrokeThickness = 2; canvas.Children.Add(line); ContentControl contentControl = new ContentControl { Content = canvas }; this.Content = contentControl; } } ``` 在这个例子中,我们首先创建了一个Canvas,然后在外圆和内圆上分别设置了样式和位置。最后,我们在内圆中心画了一条长度等于外圆半径的直线。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值