第4章---初始化UI控件(UI架构搭建)

文章详细描述了RPG游戏中ARPGGamePlayerCharacter类中的AbilitySystemComponent如何在构造函数和OnRep_PlayerState事件中进行初始化,并与PlayerState、AbilitySystemComponent、AttributeSet以及UI组件如Hud和WidgetController进行交互,特别是初始化UI的过程。
摘要由CSDN通过智能技术生成

文件结构:

更改文件将高亮显示

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<ARPGPlayerState>();
	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<ARPGPlayerController>(GetController()))
	{
		if(ARPGHUD* RPGHud = Cast<ARPGHUD>(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<URPGUserWidget> OverlayWidget;
    
    UOverlayWidgetController* GetOverlayWidgetController(const FWidgetControllerParams& WCParams);

    //初始化UI(基本上所有的UI)
    void InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS);


private:
    
    UPROPERTY(EditAnywhere)
    TSubclassOf<URPGUserWidget> OverlayWidgetClass;

    UPROPERTY()
    TObjectPtr<UOverlayWidgetController> OverlayWidgetController;

    UPROPERTY(EditAnywhere)
    TSubclassOf<UOverlayWidgetController> 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<UOverlayWidgetController>(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<UUserWidget>(GetWorld(), OverlayWidgetClass);

    //转变类同时赋值给OverlayWidget,将这个控件变成根UI
    OverlayWidget = Cast<URPGUserWidget>(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<URPGUserWidget> OverlayWidget;
    
    UOverlayWidgetController* GetOverlayWidgetController(const FWidgetControllerParams& WCParams);

    //初始化UI(基本上所有的UI)
    void InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS);


private:
    
    UPROPERTY(EditAnywhere)
    TSubclassOf<URPGUserWidget> OverlayWidgetClass;

    UPROPERTY()
    TObjectPtr<UOverlayWidgetController> OverlayWidgetController;

    UPROPERTY(EditAnywhere)
    TSubclassOf<UOverlayWidgetController> 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<UOverlayWidgetController>(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<UUserWidget>(GetWorld(), OverlayWidgetClass);

    //转变类同时赋值给OverlayWidget,将这个控件变成根UI
    OverlayWidget = Cast<URPGUserWidget>(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<APlayerController> PlayerController = nullptr;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    TObjectPtr<APlayerState> PlayerState = nullptr;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent = nullptr;
    
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    TObjectPtr<UAttributeSet> 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<APlayerController> PlayerController;

    UPROPERTY(BlueprintReadOnly, Category="WidgetController")
    TObjectPtr<APlayerState> PlayerState;

    UPROPERTY(BlueprintReadOnly, Category="WidgetController")
    TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;

    UPROPERTY(BlueprintReadOnly, Category="WidgetController")
    TObjectPtr<UAttributeSet> 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<UObject> 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();
}

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楚江_wog1st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值