写在前面的话:
可能这个标题并不太专业,以至于大家可能无法理解这个文章所要讲述的是什么内容。
首先我会给大家介绍如何将slate封装成UMG能够识别的UMG控件
然后将会给大家介绍如何将UMG传递到slate后被slate使用。
将Slate封装成UMG控件
其实从本质上讲,UMG是Slate的UObject性质的一个封装。
整个UE4的UI系统实际上是被一个完整的WidgetTree控制的。但是UMG为了完成使纯粹的C++编写的Slate与蓝图进行交互,所以每个UMG实例都会有另外一套Tree来控制。
简单的Slate封装并不需要了解UMG与slate之间的控制关系,除非你需要使你的UMG控件支持子控件。
其实做这个方面的内容是因为自己要复刻一个PS4上的游戏,其中使用了大量的2D动效,毫不夸张的说,这个动效的连续累积时间会超过9个小时。所以这无法使用大量的动画轨道来快速制作。于是我选择了自动计算轨道的方法。
首先还是要封装一个UObject类:
UCLASS()
class UMyWidget : public UWidget
{
GENERATED_UCLASS_BODY()
public:
#if WITH_EDITOR
virtual const FText GetPaletteCategory() override;
virtual void PostEditChangeProperty(struct FPropertyChangedEvent &PropertyChangedEvent) override;
#endif
protected:
virtual TSharedRef<SWidget> RebuildWidget() override;
#if WITH_EDITOR
virtual TSharedRef<SWidget> RebuildDesignWidget(TSharedRef<SWidget> Content) override;
#endif
};
就像这样,你就完成了基础声明。
逐一解释:
GetPaletteCategory:获取控制板类别,这个函数需要返回一个文本型。作用是将你创建的新的小控件显示到UMG设计区控制板的那个分类上。这个分类可以是已经存在的,也可以是不存在的。比如:
const FText UAETWidget::GetPaletteCategory()
{
return NSLOCTEXT("AETWidget", "Category", "后期处理模板");
}
PostEditChangeProperty:当你的小控件在UMG设计面板中发生属性更改的时候,就会触发这个函数。
RebuildWidget:这个是在任何时候生成全新的Slate控件时都会调用。比如携带这个小控件的UMG被创建了、重新编译了UMG、打开了蓝图控件设计器,等等。
RebuildDesignWidget:在UMG设计器中重新创建控件时被调用,但是会晚于RebuildWidget调用。
示例:
TSharedRef<SWidget> UImage::RebuildWidget()
{
MyImage = SNew(SImage)
.FlipForRightToLeftFlowDirection(bFlipForRightToLeftFlowDirection);
return MyImage.ToSharedRef();
}
注意:UWidget是一个可以主动获取世界上下文的对象,开发时,可以在UWidget中获取玩家、世界、HUD等等关于世界上下文的信息。
将UMG插入slate插槽
实际上在每个UMG被添加到视口(AddToViewport)的时候,都是封装了一个插槽,然后这个插槽会在不同情况下的引擎做出不同的处理。
但有一点,封装的这个插槽中都都只有一个slate widget。这个过程使UMG中的控件可以作为Widget Tree的一部分。
UMG的RebuildWidget中其实调用了TakeWidget。
理所当然的,下列代码基本示例了一个UMG被slate获取并添加到插槽的过程。
void SAETRegion::FlushHud()
{
FRegionChild rc = hud->GetAETWidget(aetdata, RegionID,Tag);
if (rc.widget != nullptr)
{
RootPanel->ClearChildren();
RootPanel->AddSlot(0, 0)
.HAlign(rc.HAlignment)
.VAlign(rc.VAlignment)
[
rc.widget->TakeWidget()
];
}
}
结束
------