第4章---初始化UI控件(UI架构搭建)
文件结构:
更改文件将高亮显示
(图片来源网络,侵删)
Source
- Private
- AbilitySystemComponen
- RPGAbilitySystemComponent.cpp
- RPGAttributeSet.cpp
- Character
- PGGameCharacterBase.cpp
- RPGGameEnemy.cpp
- RPGGamePlayerCharacter.cpp
- Game
- RPGGameModeBase.cpp
- Interaction
- EnemyInterface.cpp
- Player
- RPGPlayerController.cpp
- RPGPlayerState.cpp
- Actor
- RPGEffectActor.cpp
- UI
- HUD
- RPGHUD.cpp
- WidgetController
- OverlayWidgetController.cpp
- RPGWidgetController.cpp
- Widgets
- RPGUserWidget.cpp
- Public
- AbilitySystemComponent
- RPGAbilitySystemComponent.h
- RPGAttributeSet.h
- Character
- RPGGameCharacterBase.h
- RPGGameEnemy.h
- RPGGamePlayerCharacter.h
- Game
- RPGGameModeBase.h
- Interaction
- EnemyInterface.h
- Player
- RPGPlayerController.h
- RPGPlayerState.h
- Actor
- RPGEffectActor.h
- UI
- HUD
- RPGHUD.h
- WidgetController
- OverlayWidgetController.h
- RPGWidgetController.h
- Widgets
- RPGUserWidget.h
文件表述:
RPGGamePlayerCharacter
.cpp文件
在InitAbilityActorInfo()函数中
// Copyright KimiLiu #include "Character\RPGGamePlayerCharacter.h" #include "GameFramework/CharacterMovementComponent.h" #include "Player/RPGPlayerController.h" #include "Player/RPGPlayerState.h" #include "UI/HUD/RPGHUD.h" ARPGGamePlayerCharacter::ARPGGamePlayerCharacter() { //角色始终面向移动方向 GetCharacterMovement()->bOrientRotationToMovement = true; GetCharacterMovement()->RotationRate = FRotator(0.f, 400.f, 0.f); GetCharacterMovement()->bConstrainToPlane = true;//将运动约束在平面上 //角色不会面向控制器的方向 bUseControllerRotationPitch = false; bUseControllerRotationRoll = false; bUseControllerRotationYaw = false; } void ARPGGamePlayerCharacter::PossessedBy(AController* NewController) { Super::PossessedBy(NewController); // Init ability actor info for the Sever InitAbilityActorInfo(); } void ARPGGamePlayerCharacter::OnRep_PlayerState() { Super::OnRep_PlayerState(); // Init ability actor info for the Client InitAbilityActorInfo(); } void ARPGGamePlayerCharacter::InitAbilityActorInfo() { //获取PlayerState对象,调用InitAbilityActorInfo()将类自身设置为AvatarActor ARPGPlayerState* RPGPlayerState = GetPlayerState(); check(RPGPlayerState); RPGPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(RPGPlayerState, this); //不在构造器内初始化,而是在被分配了Controller后将Controller内的AbilitySystemComponent和AttributeSet赋值给当前对象 AbilitySystemComponent = RPGPlayerState->GetAbilitySystemComponent(); AttributeSet = RPGPlayerState->GetAttributeSet(); //通过player获取控制器,再获得HUD(HUD是控制器的一个参数,参考源码)再调用InitOverlay()对UI进行初始化 if(ARPGPlayerController* RPGplayerController = Cast(GetController())) { if(ARPGHUD* RPGHud = Cast(RPGplayerController->GetHUD())) { RPGHud->InitOverlay(RPGplayerController, RPGPlayerState, AbilitySystemComponent, AttributeSet); } } }
RPGHUD
HUD文件初始化
.h文件
// Copyright KimiLiu #pragma once #include "CoreMinimal.h" #include "GameFramework/HUD.h" #include "RPGHUD.generated.h" class UAttributeSet; class UAbilitySystemComponent; struct FWidgetControllerParams; class UOverlayWidgetController; class URPGUserWidget; /** * */ UCLASS() class AURA_API ARPGHUD : public AHUD { GENERATED_BODY() public: UPROPERTY() TObjectPtr OverlayWidget; UOverlayWidgetController* GetOverlayWidgetController(const FWidgetControllerParams& WCParams); //初始化UI(基本上所有的UI) void InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS); private: UPROPERTY(EditAnywhere) TSubclassOf OverlayWidgetClass; UPROPERTY() TObjectPtr OverlayWidgetController; UPROPERTY(EditAnywhere) TSubclassOf OverlayWidgetControllerClass; };
.cpp文件
// Copyright KimiLiu #include "UI/HUD/RPGHUD.h" #include "UI/WidgetController/OverlayWidgetController.h" #include "UI/Widgets/RPGUserWidget.h" //获取控件控制器,这个控制器不能是空的,如果是空的,那么就生成一个控制器,如果已经存在,那么就返回控制器 UOverlayWidgetController* ARPGHUD::GetOverlayWidgetController(const FWidgetControllerParams& WCParams) { if (OverlayWidgetController == nullptr) { OverlayWidgetController = NewObject(this, OverlayWidgetControllerClass); OverlayWidgetController->SetWidgetControllerParams(WCParams); OverlayWidgetController->BindCallbacksToDependences(); return OverlayWidgetController; } return OverlayWidgetController; } void ARPGHUD::InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS) { //确保UI控件类和UI控件控制器类都设置了,不为空 checkf(OverlayWidgetClass, TEXT("Overlay Widget Class uninitialized, please fill out BP_RPGHUD")); checkf(OverlayWidgetControllerClass, TEXT("Overlay Widget Controller Class uninitialized, please fill out BP_RPGHUD")); //创建控件,注意不是URPGWidget UUserWidget* Widget = CreateWidget(GetWorld(), OverlayWidgetClass); //转变类同时赋值给OverlayWidget,将这个控件变成根UI OverlayWidget = Cast(Widget); //创建一个UI控件控制器 const FWidgetControllerParams WidgetControllerParams(PC,PS,ASC,AS); UOverlayWidgetController* WidgetController = GetOverlayWidgetController(WidgetControllerParams); //将根UI的控件控制器设为WidgetController OverlayWidget->SetWidgetController(WidgetController); WidgetController->BroadcastInitialValues(); //显示控件 Widget->AddToViewport(); }
OverlayWidgetController
.h文件
// Copyright KimiLiu #pragma once #include "CoreMinimal.h" #include "GameFramework/HUD.h" #include "RPGHUD.generated.h" class UAttributeSet; class UAbilitySystemComponent; struct FWidgetControllerParams; class UOverlayWidgetController; class URPGUserWidget; /** * */ UCLASS() class AURA_API ARPGHUD : public AHUD { GENERATED_BODY() public: UPROPERTY() TObjectPtr OverlayWidget; UOverlayWidgetController* GetOverlayWidgetController(const FWidgetControllerParams& WCParams); //初始化UI(基本上所有的UI) void InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS); private: UPROPERTY(EditAnywhere) TSubclassOf OverlayWidgetClass; UPROPERTY() TObjectPtr OverlayWidgetController; UPROPERTY(EditAnywhere) TSubclassOf OverlayWidgetControllerClass; };
.cpp文件
// Copyright KimiLiu #include "UI/HUD/RPGHUD.h" #include "UI/WidgetController/OverlayWidgetController.h" #include "UI/Widgets/RPGUserWidget.h" //获取控件控制器,这个控制器不能是空的,如果是空的,那么就生成一个控制器,如果已经存在,那么就返回控制器 UOverlayWidgetController* ARPGHUD::GetOverlayWidgetController(const FWidgetControllerParams& WCParams) { if (OverlayWidgetController == nullptr) { OverlayWidgetController = NewObject(this, OverlayWidgetControllerClass); OverlayWidgetController->SetWidgetControllerParams(WCParams); OverlayWidgetController->BindCallbacksToDependences(); return OverlayWidgetController; } return OverlayWidgetController; } void ARPGHUD::InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS) { //确保UI控件类和UI控件控制器类都设置了,不为空 checkf(OverlayWidgetClass, TEXT("Overlay Widget Class uninitialized, please fill out BP_RPGHUD")); checkf(OverlayWidgetControllerClass, TEXT("Overlay Widget Controller Class uninitialized, please fill out BP_RPGHUD")); //创建控件,注意不是URPGWidget UUserWidget* Widget = CreateWidget(GetWorld(), OverlayWidgetClass); //转变类同时赋值给OverlayWidget,将这个控件变成根UI OverlayWidget = Cast(Widget); //创建一个UI控件控制器 const FWidgetControllerParams WidgetControllerParams(PC,PS,ASC,AS); UOverlayWidgetController* WidgetController = GetOverlayWidgetController(WidgetControllerParams); //将根UI的控件控制器设为WidgetController OverlayWidget->SetWidgetController(WidgetController); WidgetController->BroadcastInitialValues(); //显示控件 Widget->AddToViewport(); }
RPGWidgetController
.h文件
// Copyright KimiLiu #pragma once #include "CoreMinimal.h" #include "RPGWidgetController.generated.h" class UAttributeSet; class UAbilitySystemComponent; // 创建一个新的结构体,用来存储WidgetController的所有参数信息,包含控制器,玩家状态,ASC,AS USTRUCT(BlueprintType) struct FWidgetControllerParams { GENERATED_BODY(); //无参构造 FWidgetControllerParams(){} //带参构造 FWidgetControllerParams(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS) : PlayerController(PC), PlayerState(PS), AbilitySystemComponent(ASC), AttributeSet(AS){} UPROPERTY(EditAnywhere, BlueprintReadWrite) TObjectPtr PlayerController = nullptr; UPROPERTY(EditAnywhere, BlueprintReadWrite) TObjectPtr PlayerState = nullptr; UPROPERTY(EditAnywhere, BlueprintReadWrite) TObjectPtr AbilitySystemComponent = nullptr; UPROPERTY(EditAnywhere, BlueprintReadWrite) TObjectPtr AttributeSet = nullptr; }; /** * */ UCLASS() class AURA_API URPGWidgetController : public UObject { GENERATED_BODY() public: //设置控制器,玩家状态,ASC,AS UFUNCTION(BlueprintCallable) void SetWidgetControllerParams(const FWidgetControllerParams& WCParams); //虚函数,用于初始化时通知UI更新显示 virtual void BroadcastInitialValues(); //虚函数,用于绑定UI控件更新事件 virtual void BindCallbacksToDependences(); protected: UPROPERTY(BlueprintReadOnly, Category="WidgetController") TObjectPtr PlayerController; UPROPERTY(BlueprintReadOnly, Category="WidgetController") TObjectPtr PlayerState; UPROPERTY(BlueprintReadOnly, Category="WidgetController") TObjectPtr AbilitySystemComponent; UPROPERTY(BlueprintReadOnly, Category="WidgetController") TObjectPtr AttributeSet; };
.cpp文件
// Copyright KimiLiu #include "UI/WidgetController/RPGWidgetController.h" void URPGWidgetController::SetWidgetControllerParams(const FWidgetControllerParams& WCParams) { PlayerController = WCParams.PlayerController; PlayerState = WCParams.PlayerState; AbilitySystemComponent = WCParams.AbilitySystemComponent; AttributeSet = WCParams.AttributeSet; } void URPGWidgetController::BroadcastInitialValues() { } void URPGWidgetController::BindCallbacksToDependences() { }
RPGUserWidget
.h文件
// Copyright KimiLiu #pragma once #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include "RPGUserWidget.generated.h" /** * */ UCLASS() class AURA_API URPGUserWidget : public UUserWidget { GENERATED_BODY() public: UFUNCTION(BlueprintCallable) void SetWidgetController(UObject* InWidgetController); UPROPERTY(BlueprintReadOnly) TObjectPtr WidgetController; protected: /** 当该控件的WidgetController被设置时,该函数将会被调用 * 根UI会被调用WidgetControllerSet,在蓝图内调用SetWidgetController,子类蓝图的WidgetControllerSet又会被调用,可以视为一个树状 * 的结构,所有子类都会被调用到这个函数 */ UFUNCTION(BlueprintImplementableEvent) void WidgetControllerSet(); };
.cpp文件
// Copyright KimiLiu #include "UI/Widgets/RPGUserWidget.h" void URPGUserWidget::SetWidgetController(UObject* InWidgetController) { WidgetController = InWidgetController; WidgetControllerSet(); }
- RPGUserWidget.h
- HUD
- AbilitySystemComponent
- HUD
- AbilitySystemComponen
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。