①下载Github上的GASDocumentation(UE 4.26.2)或UE商场中自带的ActionRPG项目(图一的两个项目)
②下载中文版文档
本文主要用以学习记录。版本使用的是4.26.2。项目时间是2022.7.21。
此处存有GameplayCue Editor的话说明启用成功
此处存在Gameplay Ability Blueprint的话,也说明已经启用成功
由于我们创建的是C++的UE项目
万事皆有HelloWorld,GAS也不例外。
在内容浏览器中,新建一个GA BP,命名为GA_testHello。
双击进入,添加一个PrintString作为Helloworld的动作
(此处print的是一个“Action”)
GAS的最终目的就是让玩家发出技能,而玩家控制的便是——Character。因此需要为Character添加ASC(Ability System Component)。
因为我们在1.1创建项目的时候已经选择了带有初学者包,也就是说项目创建之初便带有一个默认的Character。
打开VS项目,右侧的资源管理器就记载了我们的代码。其中,项目名+Character.h
和项目名+Character.cpp
便是我们要添加ASC的Character。
打开.h文件后,需要更改几处代码:
①头文件部分
#include "AbilitySystemInterface.h"
#include "AbilitySystemComponent.h"
注意,#include "learnUe_0720Character.generated.h"
这个头文件必须在最后一个引用,否则会报错:
添加如下即可:
②添加IAbilitySystemInterface
接口
在 .h文件的第一个Public中添加如下代码 声明ASC :
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = GameplayAbilities,meta = (AllowPrivateAccess = "true"))
class UAbilitySystemComponent* AbilitySystem;
UAbilitySystemComponent* GetAbilitySystemComponent()const override;
即如下图所示
添加完 .h文件,下一步当然是添加 .cpp文件
①在文件的末尾添加如下代码:
UAbilitySystemComponent* AlearnUe_0720Character::GetAbilitySystemComponent() const
{
return AbilitySystem;
}
该函数是用来实现 h文件中3.2最后添加的UAbilitySystemComponent* GetAbilitySystemComponent()const override;
此时,可以回到UE项目中编译一下,如果编译通过,那么可以继续。
如果编译成功,可以看到我们的Character上面多了ASC:
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
//添加引用
#include "AbilitySystemInterface.h"
#include "AbilitySystemComponent.h"
//最后引用
#include "learnUe_0720Character.generated.h"
UCLASS(config=Game)
class AlearnUe_0720Character : public ACharacter , public IAbilitySystemInterface //修改:添加接口
{
GENERATED_BODY()
/** Camera boom positioning the camera behind the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** Follow camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
public:
AlearnUe_0720Character();
//modi: 声明ASC 设置为Private后蓝图是无法读取的,因此需要meta设置为true才可以被蓝图看到
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = GameplayAbilities,meta = (AllowPrivateAccess = "true"))
class UAbilitySystemComponent* AbilitySystem;
//modi:添加一个返回此组件的方法
UAbilitySystemComponent* GetAbilitySystemComponent()const override;
/** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseTurnRate;
/** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseLookUpRate;
protected:
/** Resets HMD orientation in VR. */
void OnResetVR();
/** Called for forwards/backward input */
void MoveForward(float Value);
/** Called for side to side input */
void MoveRight(float Value);
/**
* Called via input to turn at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void TurnAtRate(float Rate);
/**
* Called via input to turn look up/down at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void LookUpAtRate(float Rate);
/** Handler for when a touch input begins. */
void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);
/** Handler for when a touch input stops. */
void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// End of APawn interface
//TWeakObjectPtr AbilitySystemComponent;
public:
/** Returns CameraBoom subobject **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
/** Returns FollowCamera subobject **/
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
};
// Copyright Epic Games, Inc. All Rights Reserved.
#include "learnUe_0720Character.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
//
// AlearnUe_0720Character
AlearnUe_0720Character::AlearnUe_0720Character()
{
// Set size for collision capsule
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// set our turn rates for input
BaseTurnRate = 45.f;
BaseLookUpRate = 45.f;
// Don't rotate when the controller rotates. Let that just affect the camera.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Configure character movement
GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate
GetCharacterMovement()->JumpZVelocity = 600.f;
GetCharacterMovement()->AirControl = 0.2f;
// Create a camera boom (pulls in towards the player if there is a collision)
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character
CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
// Create a follow camera
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
AbilitySystem = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystemLearn"));
// Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character)
// are set in the derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}
//
// Input
void AlearnUe_0720Character::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// Set up gameplay key bindings
check(PlayerInputComponent);
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("MoveForward", this, &AlearnUe_0720Character::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AlearnUe_0720Character::MoveRight);
// We have 2 versions of the rotation bindings to handle different kinds of devices differently
// "turn" handles devices that provide an absolute delta, such as a mouse.
// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("TurnRate", this, &AlearnUe_0720Character::TurnAtRate);
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
PlayerInputComponent->BindAxis("LookUpRate", this, &AlearnUe_0720Character::LookUpAtRate);
// handle touch devices
PlayerInputComponent->BindTouch(IE_Pressed, this, &AlearnUe_0720Character::TouchStarted);
PlayerInputComponent->BindTouch(IE_Released, this, &AlearnUe_0720Character::TouchStopped);
// VR headset functionality
PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &AlearnUe_0720Character::OnResetVR);
}
void AlearnUe_0720Character::OnResetVR()
{
// If learnUe_0720 is added to a project via 'Add Feature' in the Unreal Editor the dependency on HeadMountedDisplay in learnUe_0720.Build.cs is not automatically propagated
// and a linker error will result.
// You will need to either:
// Add "HeadMountedDisplay" to [YourProject].Build.cs PublicDependencyModuleNames in order to build successfully (appropriate if supporting VR).
// or:
// Comment or delete the call to ResetOrientationAndPosition below (appropriate if not supporting VR)
UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition();
}
void AlearnUe_0720Character::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location)
{
Jump();
}
void AlearnUe_0720Character::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location)
{
StopJumping();
}
void AlearnUe_0720Character::TurnAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}
void AlearnUe_0720Character::LookUpAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}
void AlearnUe_0720Character::MoveForward(float Value)
{
if ((Controller != nullptr) && (Value != 0.0f))
{
// find out which way is forward
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get forward vector
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
}
void AlearnUe_0720Character::MoveRight(float Value)
{
if ( (Controller != nullptr) && (Value != 0.0f) )
{
// find out which way is right
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get right vector
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
// add movement in that direction
AddMovementInput(Direction, Value);
}
}
UAbilitySystemComponent* AlearnUe_0720Character::GetAbilitySystemComponent() const
{
return AbilitySystem;
}
注意这里是Abilities(复数),因此需要使用 For 循环来声明,确保不漏掉技能。
①在 Character.h文件的public中声明我们的技能数组:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Abilities)
TArray<TSubclassOf<class UGameplayAbility>>GA_testHello;
②在 Character.h文件的protected中声明我们的Beginplay
virtual void BeginPlay() override;
③在Character.cpp文件中,实现我们声明的Beginplay
void AlearnUe_0720Character::BeginPlay()
{
Super::BeginPlay();
if (AbilitySystem == nullptr)return;
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Char Beginplay 97"));
if (HasAuthority() && GA_testHello.Num()) {
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Char Beginplay 99"));
for (auto i = 0; i < GA_testHello.Num(); i++) {
if (GA_testHello[i] == nullptr)continue;
AbilitySystem->GiveAbility(FGameplayAbilitySpec(GA_testHello[i].GetDefaultObject(), 1, 0));
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("103_BP we regiter an ability"));
}
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("All abilities Registered"))
}
AbilitySystem->InitAbilityActorInfo(this, this);
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Char Beginplay 105"));
}
现在我们只有一个Gameplay Ability,而且还是用于演示如何创建GA BP。
现在我们要让技能丰富起来,新建一个技能GA BP,命名为GA_Fire1。
注意5.1 、 5.2 、 5.3 的标题的区别。
激活技能,当然是玩家来操作的,而玩家,则需要通过按键输入来控制。因此我们新建一个Action:
打开Project Setting → Input
然后返回Character并且编辑蓝图如下:
之后在右侧“细节”一栏中,选择我们添加的GA_Fire1。我这里没有,根据自己的GA添加就好了(如下)。
完成!
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
//添加引用
#include "AbilitySystemInterface.h"
#include "AbilitySystemComponent.h"
//最后引用
#include "learnUe_0720Character.generated.h"
UCLASS(config=Game)
class AlearnUe_0720Character : public ACharacter , public IAbilitySystemInterface //修改:添加接口
{
GENERATED_BODY()
/** Camera boom positioning the camera behind the character */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class USpringArmComponent* CameraBoom;
/** Follow camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FollowCamera;
public:
AlearnUe_0720Character();
//modi: 声明ASC 设置为Private后蓝图是无法读取的,因此需要meta设置为true才可以被蓝图看到
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = GameplayAbilities,meta = (AllowPrivateAccess = "true"))
class UAbilitySystemComponent* AbilitySystem;
//modi:添加一个返回此组件的方法
UAbilitySystemComponent* GetAbilitySystemComponent()const override;
//modi:添加Ability 暴露给蓝图方便蓝图调用
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Abilities)
TArray<TSubclassOf<class UGameplayAbility>>GA_testHello;
实现接口方法
//virtual UAbilitySystemComponent* GetAbilitySystemComponent()const override;
生命Ability数组
//UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = Abilities)
//TArray> MyAbilities;
/** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseTurnRate;
/** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseLookUpRate;
protected:
//modi:添加Beginplay的声明,在初始的Character上是没有的,需要声明一个Bplay()方便cpp调用
virtual void BeginPlay() override;
/** Resets HMD orientation in VR. */
void OnResetVR();
/** Called for forwards/backward input */
void MoveForward(float Value);
/** Called for side to side input */
void MoveRight(float Value);
/**
* Called via input to turn at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void TurnAtRate(float Rate);
/**
* Called via input to turn look up/down at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void LookUpAtRate(float Rate);
/** Handler for when a touch input begins. */
void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);
/** Handler for when a touch input stops. */
void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
// End of APawn interface
//TWeakObjectPtr AbilitySystemComponent;
public:
/** Returns CameraBoom subobject **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
/** Returns FollowCamera subobject **/
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
};
// Copyright Epic Games, Inc. All Rights Reserved.
#include "learnUe_0720Character.h"
#include "HeadMountedDisplayFunctionLibrary.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
//
// AlearnUe_0720Character
AlearnUe_0720Character::AlearnUe_0720Character()
{
// Set size for collision capsule
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// set our turn rates for input
BaseTurnRate = 45.f;
BaseLookUpRate = 45.f;
// Don't rotate when the controller rotates. Let that just affect the camera.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Configure character movement
GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate
GetCharacterMovement()->JumpZVelocity = 600.f;
GetCharacterMovement()->AirControl = 0.2f;
// Create a camera boom (pulls in towards the player if there is a collision)
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character
CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
// Create a follow camera
FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
AbilitySystem = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystemLearn"));
// Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character)
// are set in the derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}
//
// Input
void AlearnUe_0720Character::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// Set up gameplay key bindings
check(PlayerInputComponent);
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("MoveForward", this, &AlearnUe_0720Character::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AlearnUe_0720Character::MoveRight);
// We have 2 versions of the rotation bindings to handle different kinds of devices differently
// "turn" handles devices that provide an absolute delta, such as a mouse.
// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("TurnRate", this, &AlearnUe_0720Character::TurnAtRate);
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
PlayerInputComponent->BindAxis("LookUpRate", this, &AlearnUe_0720Character::LookUpAtRate);
// handle touch devices
PlayerInputComponent->BindTouch(IE_Pressed, this, &AlearnUe_0720Character::TouchStarted);
PlayerInputComponent->BindTouch(IE_Released, this, &AlearnUe_0720Character::TouchStopped);
// VR headset functionality
PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &AlearnUe_0720Character::OnResetVR);
}
void AlearnUe_0720Character::OnResetVR()
{
// If learnUe_0720 is added to a project via 'Add Feature' in the Unreal Editor the dependency on HeadMountedDisplay in learnUe_0720.Build.cs is not automatically propagated
// and a linker error will result.
// You will need to either:
// Add "HeadMountedDisplay" to [YourProject].Build.cs PublicDependencyModuleNames in order to build successfully (appropriate if supporting VR).
// or:
// Comment or delete the call to ResetOrientationAndPosition below (appropriate if not supporting VR)
UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition();
}
void AlearnUe_0720Character::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location)
{
Jump();
}
void AlearnUe_0720Character::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location)
{
StopJumping();
}
void AlearnUe_0720Character::TurnAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
}
void AlearnUe_0720Character::LookUpAtRate(float Rate)
{
// calculate delta for this frame from the rate information
AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
}
void AlearnUe_0720Character::MoveForward(float Value)
{
if ((Controller != nullptr) && (Value != 0.0f))
{
// find out which way is forward
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get forward vector
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, Value);
}
}
void AlearnUe_0720Character::MoveRight(float Value)
{
if ( (Controller != nullptr) && (Value != 0.0f) )
{
// find out which way is right
const FRotator Rotation = Controller->GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// get right vector
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
// add movement in that direction
AddMovementInput(Direction, Value);
}
}
//modi: 登记Ability
void AlearnUe_0720Character::BeginPlay()
{
Super::BeginPlay();
if (AbilitySystem == nullptr)return;
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Char Beginplay 97"));
if (HasAuthority() && GA_testHello.Num()) {
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Char Beginplay 99"));
for (auto i = 0; i < GA_testHello.Num(); i++) {
if (GA_testHello[i] == nullptr)continue;
AbilitySystem->GiveAbility(FGameplayAbilitySpec(GA_testHello[i].GetDefaultObject(), 1, 0));
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("103_BP we regiter an ability"));
}
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("All abilities Registered"))
}
AbilitySystem->InitAbilityActorInfo(this, this);
UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("Char Beginplay 105"));
}
UAbilitySystemComponent* AlearnUe_0720Character::GetAbilitySystemComponent() const
{
return AbilitySystem;
}
①新建一个GA_test2
②设置蓝图如下:
其中,Exc Count为自定义变量,“ ++ ” 蓝图搜索 “ increment Int ”,该蓝图的功能类似:
Exc Count ++;