|
執筆バージョン: Unreal Engine 5.8.0
|
こんにちは。エンタープライズエンジニアの方井です。
UE5.7の頃から、UMGのWidgetを選択すると右上に知らない選択画面が出ていないでしょうか?

そうそう、これこれ
なんでしょうかこれ。WidgetにComponent?聞いたことがないな…いや、どこかで見たぞこれ!
UE5で作成するUIと最適化手法

これだああああ!!
どうやら既存のWidgetをなるべく壊さないように手を加えるために追加された機能のようです。メモリの観点でも軽量みたいです。
現在提供されているUI ComponentはUUIComponentのドキュメントを確認すると、
UMouseHoverComponent・UNavigationUIComponent・UScaleBoxComponent・USizeBoxComponentのようです。
痒い所に手が届くものではありますが、どうせなら大きく見た目が変化するものを作成してみましょう。
1. 新規プロジェクト作成

リスポーン地点のような安心感。新規プロジェクト作成画面です。どれでも良いですが、今回はThirdPersonTemplateを選びます。また、UI ComponentはC++でしか拡張できないため、C++で作成します。
2. 自作のBlur UI Componentを作成する
手法は問いません。C++でUUIComponentを作成します。そして、以下のヘッダーファイルのようにSlateの背景ブラーを持つクラスにします。自作だと分かりやすいよう、名前は主張激しめにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
#pragma once #include "CoreMinimal.h" #include "Extensions/UIComponent.h" #include "BlurUIComponent.generated.h" class SBackgroundBlur; class SOverlay; UCLASS(MinimalAPI) class /*UICOMPONENTTEST_API*/ UXXXXXXXXXXXXXXXXXXXXXXXXBlurUIComponent : public UUIComponent { GENERATED_BODY() public: UICOMPONENTTEST_API void SetBlurStrength(const float newStrength); UICOMPONENTTEST_API float GetBlurStrength()const { return BlurStrength; } #if WITH_EDITOR virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override; #endif virtual TSharedRef RebuildWidgetWithContent(const TSharedRef OwnerContent) override; private: void SynchronizeProperties(TSharedRef blur); TWeakPtr MyBlur; TWeakPtr MyOverlay; UPROPERTY(EditAnywhere, BlueprintReadWrite, Getter, Setter, Category = "Blur", meta = (AllowPrivateAccess = true)) float BlurStrength = 3.0f; }; |
ソースファイルは以下のような形です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
#include "UI/BlurUIComponent.h" #include "Widgets/Layout/SBackgroundBlur.h" #include "Widgets/SOverlay.h" void UXXXXXXXXXXXXXXXXXXXXXXXXBlurUIComponent::SetBlurStrength(const float newStrength) { BlurStrength = newStrength; if (const TSharedPtr blur = MyBlur.Pin()) { blur->SetBlurStrength(newStrength); } } #if WITH_EDITOR void UXXXXXXXXXXXXXXXXXXXXXXXXBlurUIComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) { Super::PostEditChangeProperty(PropertyChangedEvent); if (const TSharedPtr blur = MyBlur.Pin()) { SynchronizeProperties(blur.ToSharedRef()); } } #endif TSharedRef UXXXXXXXXXXXXXXXXXXXXXXXXBlurUIComponent::RebuildWidgetWithContent(const TSharedRef OwnerContent) { TSharedRef backgroundBlur = SNew(SBackgroundBlur) .BlurStrength(BlurStrength) .Padding(0.f); MyBlur = backgroundBlur.ToWeakPtr(); TSharedRef overlay = SNew(SOverlay) + SOverlay::Slot()[ OwnerContent ] + SOverlay::Slot()[ backgroundBlur ]; return overlay; } void UXXXXXXXXXXXXXXXXXXXXXXXXBlurUIComponent::SynchronizeProperties(TSharedRef blur) { blur->SetBlurStrength(BlurStrength); } |
基本的な実装は4つのUI ComponentとUBackgroundBlurを参考に、最小構成で行っております。
やってることは単純です。Widget情報を基にSlateを構築する際に、割り込んでSlateを差し込んでいます。
(RebuildWidgetWithContent関数にて、OvarlayでOwnerContent(元のWidgetの内容)とBlurを囲っている)
そうです、これってSlate Injectionなんです!!
メモリの観点でも軽量というのは、Widgetで囲う従来の階層を変更する手法だとWidget分のUObjectが増加してメモリが増えてしまうということですね。これなら本来描画に必要なSlate部分の増加のみで済むためスマートです。
(今回の例ではOvarlayとBlurの2個分の内容が、UIComponent1個分で済んでいる)
3. 自作のBlur UI Componentを使用する
簡単です。好きなWidgetに付与するだけです。

Imageに自作のBlurを付与している
これで見事UI Componentを自作することができました!!UI Componentを追加すると、それの設定欄がDetailsに追加されます。今回の例ならば、Blurの強さが変更できます。
UI Componentの使い道ですが冒頭の資料通り、例えば運用タイトルなどで既存のUIを大きく変更できない場合に、味変程度の小さな変更ならばC++で書いてしまうのも良いのかもしれません。でも、要Slate知識です!エンジニアさんに相談しましょう!
以上で、UI Componentの説明は終了です。
それではに、良きUMG生活を!!