文件结构:
更改文件将高亮显示
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
- HUD
- AbilitySystemComponen
- 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
- HUD
- AbilitySystemComponent
文件表述:
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();
}