六一的部落格


关关难过关关过,前路漫漫亦灿灿。



Player Character / Refactoring


说明

STUBaseCharacter作为STUAICharacter和STUPlayerCharacter的基类


创建STUPlayerCharacter

-
基类 STUBaseCharacter
路径 Player
名称 STUPlayerCharacter
属性 Public

从STUBaseCharacter中移除文本组件

下一章会给出其他实现

ShootThemUp: Player/STUBaseCharacter.h

1// class UTextRenderComponent;
2
3/*
4  UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
5  UTextRenderComponent *HealthTextComponent;
6*/         

ShootThemUp: Player/STUBaseCharacter.cpp

 1// #include "Components/TextRenderComponent.h"
 2
 3// 构造函数
 4
 5/*
 6  HealthTextComponent = CreateDefaultSubobject<UTextRenderComponent>("HealthTextComponent");
 7  HealthTextComponent->SetupAttachment(GetRootComponent());
 8  HealthTextComponent->SetOwnerNoSee(true);
 9*/
10
11// BeginPlay
12
13// check(HealthTextComponent);
14// HealthTextComponent->SetText(FText::FromString(FString::Printf(TEXT("%.0f"), HealthComponent->GetHealth())));
15
16// OnChangeHealth
17// HealthTextComponent->SetText(FText::FromString(FString::Printf(TEXT("%.0f"), HealthComponent->GetHealth())));

弹簧臂组件和摄像机组件


在STUPlayerCharacter中实现

ShootThemUp: Player/STUPlayerCharacter.h

 1// public
 2ASTUPlayerCharacter(const FObjectInitializer &ObjInit);
 3
 4//protected
 5
 6UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components")
 7UCameraComponent *CameraComponent;
 8
 9UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components")
10USpringArmComponent *SpringArmComponent;

ShootThemUp: Player/STUPlayerCharacter.cpp

 1#include "Camera/CameraComponent.h"
 2#include "GameFrameWork/SpringArmComponent.h"
 3
 4ASTUPlayerCharacter::ASTUPlayerCharacter(const FObjectInitializer &ObjInit) : Super(ObjInit)
 5{
 6    PrimaryActorTick.bCanEverTick = true;
 7
 8    SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>("SpringArmComponent");
 9    SpringArmComponent->SetupAttachment(GetRootComponent());
10    SpringArmComponent->bUsePawnControlRotation = true;
11    SpringArmComponent->SocketOffset = FVector(0.0f, 100.0f, 80.0f);
12
13    CameraComponent = CreateDefaultSubobject<UCameraComponent>("CameraComponent");
14    CameraComponent->SetupAttachment(SpringArmComponent);
15}

屏蔽STUBaseCharacter的弹簧臂组件和摄像机组件


键位绑定


在STUPlayerCharacter中实现

ShootThemUp: Player/STUPlayerCharacter.cpp

 1#include "Components/InputComponent.h"
 2#include "Components/STUWeaponComponent.h"
 3
 4void ASTUPlayerCharacter::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent)
 5{
 6    Super::SetupPlayerInputComponent(PlayerInputComponent);
 7
 8    PlayerInputComponent->BindAxis("MoveForward", this, &ASTUPlayerCharacter::MoveForward);
 9    PlayerInputComponent->BindAxis("MoveRight", this, &ASTUPlayerCharacter::MoveRight);
10    PlayerInputComponent->BindAxis("Lookup", this, &ASTUPlayerCharacter::AddControllerPitchInput);
11    PlayerInputComponent->BindAxis("TurnAround", this, &ASTUPlayerCharacter::AddControllerYawInput);
12    PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ASTUPlayerCharacter::Jump);
13    PlayerInputComponent->BindAction("Run", IE_Pressed, this, &ASTUPlayerCharacter::RunEnable);
14    PlayerInputComponent->BindAction("Run", IE_Released, this, &ASTUPlayerCharacter::RunDisable);
15    PlayerInputComponent->BindAction("Fire", IE_Pressed, WeaponComponent, &USTUWeaponComponent::FireStart);
16    PlayerInputComponent->BindAction("Fire", IE_Released, WeaponComponent, &USTUWeaponComponent::FireStop);
17    PlayerInputComponent->BindAction("NextWeapon", IE_Pressed, WeaponComponent, &USTUWeaponComponent::NextWeapon);
18    PlayerInputComponent->BindAction("Reload", IE_Pressed, WeaponComponent, &USTUWeaponComponent::Reload);
19}
20
21void ASTUPlayerCharacter::MoveForward(float Amount)
22{
23    IsForward = Amount > 0.0f;
24    if (Amount == 0.0f) return;
25    AddMovementInput(GetActorForwardVector(), Amount);
26}
27
28void ASTUPlayerCharacter::MoveRight(float Amount)
29{
30    if (Amount == 0.0f) return;
31    AddMovementInput(GetActorRightVector(), Amount);
32}
33
34void ASTUPlayerCharacter::RunEnable()
35{
36    AbleRun = true;
37}
38
39void ASTUPlayerCharacter::RunDisable()
40{
41    AbleRun = false;
42}

ShootThemUp: Player/STUPlayerCharacter.h

 1// public
 2virtual void SetupPlayerInputComponent(class UInputComponent *PlayerInputComponent) override;
 3
 4// private
 5
 6bool IsForward = false;
 7bool AbleRun = false;
 8
 9void MoveForward(float Amount);
10void MoveRight(float Amount);
11
12void RunEnable();
13void RunDisable();

屏蔽STUBaseCharacter的键位绑定


动画蓝图和游戏角色运动组件使用IsRunning接口


STUBaseCharacter将之设为虚函数, 返回false

ShootThemUp: Player/STUBaseCharacter.h

1UFUNCTION(BlueprintCallable)
2virtual bool IsRunning() const;

ShootThemUp: Player/STUBaseCharacter.cpp

1bool ASTUBaseCharacter::IsRunning() const
2{
3    return false;
4}

STUPlayerCharacter对其覆写

不需要给出UFUNCTION

ShootThemUp: Player/STUPlayerCharacter.h

1virtual bool IsRunning() const override;

ShootThemUp: Player/STUPlayerCharacter.cpp

1bool ASTUPlayerCharacter::IsRunning() const
2{
3    return AbleRun && IsForward && !GetVelocity().IsZero();
4}

游戏角色死亡时切换到观察者状态


STUBaseCharacter屏蔽OnDeath中切换控制器状态

ShootThemUp: Player/STUBaseCharacter.cpp

1// #include "GameFramework/Controller.h"
2
3/*
4  if (Controller)
5  {
6  Controller->ChangeState(NAME_Spectating);
7  }
8*/

STUPlayerCharacter覆写OnDeath

ShootThemUp: Player/STUPlayerCharacter.h

1virtual void OnDeath() override;

ShootThemUp: Player/STUPlayerCharacter.cpp

 1#include "GameFramework/Controller.h"
 2
 3void ASTUPlayerCharacter::OnDeath()
 4{
 5    Super::OnDeath();
 6
 7    if (Controller)
 8    {
 9        Controller->ChangeState(NAME_Spectating);
10    }
11}

关卡使用STUPlayerCharacter

  1. 创建基于STUPlayerCharacter的蓝图类, 命名为BP_STUPlayerCharacter, 保存到 Content/Player

  2. 设置关卡DefaultPawnClass



设置BP_STUPlayerCharacter

参照 进阶课程 > 非玩家游戏角色行为 > 让NPC移动到指定位置 > 配置BP_STUAICharacter

至此, 可以删除BP_STUBaseCharacter


重构游戏角色类


Player Character / Refactoring


说明

STUBaseCharacter作为STUAICharacter和STUPlayerCharacter的基类


创建STUPlayerCharacter

-
基类 STUBaseCharacter
路径 Player
名称 STUPlayerCharacter
属性 Public

从STUBaseCharacter中移除文本组件

下一章会给出其他实现

ShootThemUp: Player/STUBaseCharacter.h

1// class UTextRenderComponent;
2
3/*
4  UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
5  UTextRenderComponent *HealthTextComponent;
6*/         

ShootThemUp: Player/STUBaseCharacter.cpp

 1// #include "Components/TextRenderComponent.h"
 2
 3// 构造函数
 4
 5/*
 6  HealthTextComponent = CreateDefaultSubobject<UTextRenderComponent>("HealthTextComponent");
 7  HealthTextComponent->SetupAttachment(GetRootComponent());
 8  HealthTextComponent->SetOwnerNoSee(true);
 9*/
10
11// BeginPlay
12
13// check(HealthTextComponent);
14// HealthTextComponent->SetText(FText::FromString(FString::Printf(TEXT("%.0f"), HealthComponent->GetHealth())));
15
16// OnChangeHealth
17// HealthTextComponent->SetText(FText::FromString(FString::Printf(TEXT("%.0f"), HealthComponent->GetHealth())));

弹簧臂组件和摄像机组件


在STUPlayerCharacter中实现

ShootThemUp: Player/STUPlayerCharacter.h

 1// public
 2ASTUPlayerCharacter(const FObjectInitializer &ObjInit);
 3
 4//protected
 5
 6UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components")
 7UCameraComponent *CameraComponent;
 8
 9UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Components")
10USpringArmComponent *SpringArmComponent;

ShootThemUp: Player/STUPlayerCharacter.cpp

 1#include "Camera/CameraComponent.h"
 2#include "GameFrameWork/SpringArmComponent.h"
 3
 4ASTUPlayerCharacter::ASTUPlayerCharacter(const FObjectInitializer &ObjInit) : Super(ObjInit)
 5{
 6    PrimaryActorTick.bCanEverTick = true;
 7
 8    SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>("SpringArmComponent");
 9    SpringArmComponent->SetupAttachment(GetRootComponent());
10    SpringArmComponent->bUsePawnControlRotation = true;
11    SpringArmComponent->SocketOffset = FVector(0.0f, 100.0f, 80.0f);
12
13    CameraComponent = CreateDefaultSubobject<UCameraComponent>("CameraComponent");
14    CameraComponent->SetupAttachment(SpringArmComponent);
15}

屏蔽STUBaseCharacter的弹簧臂组件和摄像机组件


键位绑定


在STUPlayerCharacter中实现

ShootThemUp: Player/STUPlayerCharacter.cpp

 1#include "Components/InputComponent.h"
 2#include "Components/STUWeaponComponent.h"
 3
 4void ASTUPlayerCharacter::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent)
 5{
 6    Super::SetupPlayerInputComponent(PlayerInputComponent);
 7
 8    PlayerInputComponent->BindAxis("MoveForward", this, &ASTUPlayerCharacter::MoveForward);
 9    PlayerInputComponent->BindAxis("MoveRight", this, &ASTUPlayerCharacter::MoveRight);
10    PlayerInputComponent->BindAxis("Lookup", this, &ASTUPlayerCharacter::AddControllerPitchInput);
11    PlayerInputComponent->BindAxis("TurnAround", this, &ASTUPlayerCharacter::AddControllerYawInput);
12    PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ASTUPlayerCharacter::Jump);
13    PlayerInputComponent->BindAction("Run", IE_Pressed, this, &ASTUPlayerCharacter::RunEnable);
14    PlayerInputComponent->BindAction("Run", IE_Released, this, &ASTUPlayerCharacter::RunDisable);
15    PlayerInputComponent->BindAction("Fire", IE_Pressed, WeaponComponent, &USTUWeaponComponent::FireStart);
16    PlayerInputComponent->BindAction("Fire", IE_Released, WeaponComponent, &USTUWeaponComponent::FireStop);
17    PlayerInputComponent->BindAction("NextWeapon", IE_Pressed, WeaponComponent, &USTUWeaponComponent::NextWeapon);
18    PlayerInputComponent->BindAction("Reload", IE_Pressed, WeaponComponent, &USTUWeaponComponent::Reload);
19}
20
21void ASTUPlayerCharacter::MoveForward(float Amount)
22{
23    IsForward = Amount > 0.0f;
24    if (Amount == 0.0f) return;
25    AddMovementInput(GetActorForwardVector(), Amount);
26}
27
28void ASTUPlayerCharacter::MoveRight(float Amount)
29{
30    if (Amount == 0.0f) return;
31    AddMovementInput(GetActorRightVector(), Amount);
32}
33
34void ASTUPlayerCharacter::RunEnable()
35{
36    AbleRun = true;
37}
38
39void ASTUPlayerCharacter::RunDisable()
40{
41    AbleRun = false;
42}

ShootThemUp: Player/STUPlayerCharacter.h

 1// public
 2virtual void SetupPlayerInputComponent(class UInputComponent *PlayerInputComponent) override;
 3
 4// private
 5
 6bool IsForward = false;
 7bool AbleRun = false;
 8
 9void MoveForward(float Amount);
10void MoveRight(float Amount);
11
12void RunEnable();
13void RunDisable();

屏蔽STUBaseCharacter的键位绑定


动画蓝图和游戏角色运动组件使用IsRunning接口


STUBaseCharacter将之设为虚函数, 返回false

ShootThemUp: Player/STUBaseCharacter.h

1UFUNCTION(BlueprintCallable)
2virtual bool IsRunning() const;

ShootThemUp: Player/STUBaseCharacter.cpp

1bool ASTUBaseCharacter::IsRunning() const
2{
3    return false;
4}

STUPlayerCharacter对其覆写

不需要给出UFUNCTION

ShootThemUp: Player/STUPlayerCharacter.h

1virtual bool IsRunning() const override;

ShootThemUp: Player/STUPlayerCharacter.cpp

1bool ASTUPlayerCharacter::IsRunning() const
2{
3    return AbleRun && IsForward && !GetVelocity().IsZero();
4}

游戏角色死亡时切换到观察者状态


STUBaseCharacter屏蔽OnDeath中切换控制器状态

ShootThemUp: Player/STUBaseCharacter.cpp

1// #include "GameFramework/Controller.h"
2
3/*
4  if (Controller)
5  {
6  Controller->ChangeState(NAME_Spectating);
7  }
8*/

STUPlayerCharacter覆写OnDeath

ShootThemUp: Player/STUPlayerCharacter.h

1virtual void OnDeath() override;

ShootThemUp: Player/STUPlayerCharacter.cpp

 1#include "GameFramework/Controller.h"
 2
 3void ASTUPlayerCharacter::OnDeath()
 4{
 5    Super::OnDeath();
 6
 7    if (Controller)
 8    {
 9        Controller->ChangeState(NAME_Spectating);
10    }
11}

关卡使用STUPlayerCharacter

  1. 创建基于STUPlayerCharacter的蓝图类, 命名为BP_STUPlayerCharacter, 保存到 Content/Player

  2. 设置关卡DefaultPawnClass



设置BP_STUPlayerCharacter

参照 进阶课程 > 非玩家游戏角色行为 > 让NPC移动到指定位置 > 配置BP_STUAICharacter

至此, 可以删除BP_STUBaseCharacter