classDiagram
note for HUD "HUDは全てを含む"
note for AuraUserWidget "AuraUserWidgetはControllerを持っている"
note for AuraUserWidgetController "ControllerはWidgetを知る必要がない"
class HUD{
+OverlayWidget
-OverlayWidgetController
-OverlayWidgetClass
-OverlayWidgetControllerClass
+GetOverlayWidgetController()
+SetOverlayWidgetController(FWidgetControllerParams)
+InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS)
}
class AuraUserWidget {
+WidgetController
+SetWidgetController()
-WidgetControllerSet()
}
class AuraUserWidgetController {
-SetWidgetControllerParams()
+PlayerController
+PlayerState
+AbilitySystemComponent
+AttributeSet
}
class FWidgetControllerParams {
+PlayerController
+PlayerState
+AbilitySystemComponent
+AttributeSet
}
class BP_OverlayWidget{
}
class OverlayWdigetController {
}
OverlayWdigetController --|> AuraUserWidgetController : Inheritance
BP_OverlayWidget --|> AuraUserWidget : Inheritance
AuraUserWidgetController --* AuraUserWidget : Composition
OverlayWdigetController --* BP_OverlayWidget : Composition
BP_OverlayWidget --* HUD : Composition
FWidgetControllerParams ..> AuraUserWidget : Defined in this
概要
section 05 UI
- Use UUserWidget BP Class to implement Widgets
- Creating Widget and Widget Controller C++ class.
- Creating a WBP derived from Widget class.
- Making WBP reusable in other classes, Setting up contents in Hierachybars Variable.
- Setting up those variables by Blueprint
- When setting up padding “Slot as Overlay Slot” was used.
- Making HUD Class.
- In the HUD class, make a overlay variable.
- BP_HUD class.
- Also creating a HUD Controller class
- Creating and add to viewport overlay widget
- Setting up Widget Controller
- Creating
struct FWidgetControllerParams - Creating Setter for controller based on FWidgetControllerParams.
- Creating
- Init Widgets Function in HUD. Execute in CharacterController
- Create Delegate for OnHealthChange
- Use DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam
- Setup Broadcast in Init
- Bindcallback in Controller
- ASC already has a delegate for valuechange:
GetGameplayAttributeValueChangeDelegate - Bind Function to it and in that funtion, broadcasting controller’s onchanged delegate is a good way
- ASC already has a delegate for valuechange:
- Setup Mana
発見
Setting up Images by Slate Brush
Slate Brushを使ってImagesのSet Brush関数で画像を定義した。

Hierarchie of HUD
Delegate について続き。
Delegateは、いろんな関数のAdressをStoreしたもの。で、UEの場合、そのDelegateの定義は
OverlayWidgetController.cpp
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChangedSignature, float, NewHealth);のようにする。これで定義したDelegateの変数の定義は
OverlayWidgetController.cpp
UPROPERTY(BlueprintAssignable, Category = "GAS|Attributes")
FOnHealthChangedSignature OnHealthChanged;のようにしておき、この変数の中に関数のアドレスを入れるのに使うのは、他のcppファイルでやる。例えばWidgetはControllerを知っているけど、Controllerは知らないので、
OverlayWidget.cpp
void UOverlayWidget::WidgetControllerSet()
{
WidgetController->OnHealthChanged.AddDynamic(this, &UOverlayWidget::OnHealthChanged)
}
void UOverlayWidget::OnHealthChanged(float NewHealth)
{
percent = NewHealth / MaxHealth;
}こんな感じに設定する。それで、このOnHealthChangedを呼びたいときは、
OverlayWidgetController.cpp
void UOverlayWidgetController::DealDamage()
{
Health -= 10;
OnScoreChangedDelegate.Broadcast(Health)
}としている。けど、なんでControllerはWidget本体を知らない方がいいのか……?


これらについてもう少し考えてみる。
つまりは、ControllerがCharacterとかのデータのやり取りを全てしており、WidgetがControllerにアクセスすればすべての欲しいものがあると。それから、全部のWidgetをTickさせながらアクセスするのは馬鹿らしいので、ControllerがDelegateを持って、Widget側がそれに関数をAssignさせ、Widgetに依存せずに知らないControllerが淡々とTickとUpdateをしていくわけだ。
こうすることによって、Widgetの数が増えても、考えるべきなのはWidgetの中でDelegateにAssignする関数だけで済むし、Controllerは淡々と必用なVariablesを必用に応じてUpdateして、Delegateの実行、つまりBroadCastをしていくだけである。複雑になってもこれは変わらないので、Module性が高まる。
Slot as Overlay SlotなどのUI関連
Comprehensiveなチュートリアルとかドキュメントとかを読む必要あり。