AGS课程笔记

第一章:添加玩家角色并控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
26-35  HUD血量和蓝量UI制作及更新数据 UI文件夹 AuraHUD  Widget overlayWidget
36-41 GE捡到瓶子增加生命和法力
42-44-47 异常附着
48-62 标签
63-73 数据表
74-94 属性菜单
95-109 技能异步及火球发射
110-124 火球发射和击中怪物,怪物减血
125-129 多敌人类型及敌人属性
130-146 对属性计算,暴击啥的
147-160 网络?
161-174 敌人AI寻路避障
175-187 敌人近战攻击行为和对玩家造成伤害
188-196 敌人远程特殊攻击? 弹弓发射
197-200 敌人法师攻击

2-27 音乐粒子特效召唤?
28-32 场景搭建
33-46 场景微调 技能和经验UI
47-61 等级
62-67 向玩家状态添加属性作为成员变量及属性菜单升级
68-100 技能菜单
101-113 技能效果,检疫
114-135 技能升级效果,雷电技能
136-142 被动技能
143-160 水晶技能 冷却
161-169 火焰爆炸
170-192 保存

1-14 保存世界
15-31 地图入口

第一节:添加CPP基类

  1. 创建新项目

  2. 创建C++抽象角色类玩家和怪物都继承自这个类,命名AuraCharacterBase,

  3. 文件夹分类为Character

    • 删除没必要的函数,修改PrimaryActorTick.bCanEverTick = truePrimaryActorTick.bCanEverTick = false

    • AAuraCharacterBase.h

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // Fill out your copyright notice in the Description page of Project Settings.
    #pragma once

    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "AuraCharacterBase.generated.h"

    UCLASS(Abstract)
    class GAS_API AAuraCharacterBase : public ACharacter
    {
    GENERATED_BODY()

    public:
    // Sets default values for this character's properties
    AAuraCharacterBase();

    protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
    };

    • AAuraCharacterBase.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // Fill out your copyright notice in the Description page of Project Settings.


    #include "Character/AuraCharacterBase.h"

    // Sets default values
    AAuraCharacterBase::AAuraCharacterBase()
    {
    // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = false;
    }

    // Called when the game starts or when spawned
    void AAuraCharacterBase::BeginPlay()
    {
    Super::BeginPlay();

    }

  4. 添加装备组件

    • AAuraCharacterBase.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // Fill out your copyright notice in the Description page of Project Settings.

    #pragma once

    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "AuraCharacterBase.generated.h"

    UCLASS(Abstract)
    class GAS_API AAuraCharacterBase : public ACharacter
    {
    GENERATED_BODY()

    public:
    // Sets default values for this character's properties
    AAuraCharacterBase();

    protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

    //智能指针
    UPROPERTY(EditAnywhere, Category = "Combat")
    TObjectPtr<USkeletalMeshComponent>Weapon;
    };

    • AAuraCharacterBase.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // Fill out your copyright notice in the Description page of Project Settings.


    #include "Character/AuraCharacterBase.h"

    // Sets default values
    AAuraCharacterBase::AAuraCharacterBase()
    {
    // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = false;

    //挂载,设置碰撞
    Weapon=CreateDefaultSubobject<USkeletalMeshComponent>("Weapon");
    Weapon->SetupAttachment(GetMesh(), FName("WeaponSocket"));
    Weapon->SetCollisionEnabled(ECollisionEnabled::NoCollision);
    }

    // Called when the game starts or when spawned
    void AAuraCharacterBase::BeginPlay()
    {
    Super::BeginPlay();
    }
  5. 创建继承自AuraCharacterBase的子类,分别为玩家Player和怪物Enemy

第二节:角色动画和装备武器

  1. 创建角色蓝图,继承C++子类,角色继承Player,怪物继承Enemy

  2. 将角色网格体设置为角色网格体QQ截图20240922025724

  3. 武器绑定武器绑定

  4. 调整绑定武器添加绑定武器

  5. 调整绑定武器调整武器

第三节 :角色状态机和动画

  1. 创建状态机创建状态机
  2. 链接状态机链接状态机
  3. 添加动画添加状态
  4. 链接混合动画链接混合动画
  5. 动画事件图表布尔角色状态机动画事件图表
  6. 打开角色蓝图角色绑定蓝图动画
  7. 将角色拖到进场景测试

第四节:怪物动画

  1. 武器绑定同玩家的武器绑定

  2. 添加动画蓝图创建怪物动作模板创建怪物动画模板

  3. 模板状态机怪物状态机

添加怪物状态机

  1. 混合状态混合状态blend

  2. 添加怪物状态机正式添加怪物状态机

  3. 设置混合动画设置怪物状态混合空间

第五节:增强输入系统

  1. 添加输入操作,更改输入值类型添加输入操作
  2. 添加输入映射添加输入映射

调整输入映射

  1. 添加玩家控制器C++类,Player文件夹

    • 头文件AuraPlayerController.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    // Fill out your copyright notice in the Description page of Project Settings.

    #pragma once

    #include "CoreMinimal.h"
    #include "GameFramework/PlayerController.h"
    #include "AuraPlayerController.generated.h"

    class UInputMappingContext;
    class UInputAction;
    struct FInputActionValue;
    /**
    *
    */
    UCLASS()
    class GAS_API AAuraPlayerController : public APlayerController
    {
    GENERATED_BODY()
    public:
    AAuraPlayerController();
    protected:
    virtual void BeginPlay() override;
    virtual void SetupInputComponent() override;
    private:
    UPROPERTY(EditAnywhere, category = "Input");
    TObjectPtr<UInputMappingContext> AuraContext;

    UPROPERTY(EditAnywhere, category = "Input");
    TObjectPtr<UInputAction> MoveAction;

    void Move(const FInputActionValue& InputActionValue);


    };

    • 源文件AuraPlayerController.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    // Fill out your copyright notice in the Description page of Project Settings.


    #include "Player/AuraPlayerController.h"
    #include "EnhancedInputSubsystems.h"
    #include "EnhancedInputComponent.h"


    AAuraPlayerController::AAuraPlayerController()
    {
    bReplicates = true;
    }

    void AAuraPlayerController::BeginPlay()
    {
    Super::BeginPlay();
    //检查输入映射是否有效
    check(AuraContext);

    //获取增强输入系统
    UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());

    //添加映射上下文
    Subsystem->AddMappingContext(AuraContext, 0);

    bShowMouseCursor = true;
    DefaultMouseCursor = EMouseCursor::Default;

    FInputModeGameAndUI InputModeData;
    InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
    InputModeData.SetHideCursorDuringCapture(false);
    SetInputMode(InputModeData);


    }

    void AAuraPlayerController::SetupInputComponent()
    {
    Super::SetupInputComponent();

    UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(InputComponent);

    EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AAuraPlayerController::Move);
    }

    void AAuraPlayerController::Move(const FInputActionValue& InputActionValue)
    {
    const FVector2D InputAxisVector = InputActionValue.Get<FVector2D>();
    const FRotator Rotation = GetControlRotation();
    const FRotator YawRotation(0.f, Rotation.Yaw, 0.f);

    const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
    const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

    if (APawn* ControlledPawn = GetPawn<APawn>())
    {
    ControlledPawn->AddMovementInput(RightDirection * InputAxisVector.Y);
    ControlledPawn->AddMovementInput(ForwardDirection * InputAxisVector.X);

    }
    }
    1. 创建继承自AuraPlayerController的蓝图类
    2. 选择控制器映射和控制器
    3. 添加游戏基础模式蓝图
    4. 选择玩家控制器及玩家蓝图游戏模式设置
    5. 在游戏世界场景切换游戏模式,添加玩家出生点并运行

第六节:添加相机及设置角色选择

  1. 打开角色蓝图添加弹簧臂

  2. 弹簧臂下添加相机,通过调整弹簧臂设置相机位置及角度

  3. 前往玩家CPP类,AuraCharacter.h,控制玩家旋转

    • 头文件AuraCharacter.h
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // Fill out your copyright notice in the Description page of Project Settings.

    #pragma once

    #include "CoreMinimal.h"
    #include "Character/AuraCharacterBase.h"
    #include "AuraCharacter.generated.h"

    /**
    *
    */
    UCLASS()
    class GAS_API AAuraCharacter : public AAuraCharacterBase
    {
    GENERATED_BODY()
    public:
    AAuraCharacter();
    };

    • 源文件AuraCharacter.cpp
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // Fill out your copyright notice in the Description page of Project Settings.


    #include "Character/AuraCharacter.h"
    #include "GameFramework/CharacterMovementComponent.h"


    AAuraCharacter::AAuraCharacter()
    {
    GetCharacterMovement()->bOrientRotationToMovement = true;
    GetCharacterMovement()->RotationRate=FRotator(0.0, 400.0f, 0.0);
    GetCharacterMovement()->bConstrainToPlane=true;
    GetCharacterMovement()->bSnapToPlaneAtStart=true;

    bUseControllerRotationRoll = false;
    bUseControllerRotationPitch = false;
    bUseControllerRotationYaw = false;
    }
  4. 返回引擎,打开角色蓝图,将弹簧臂

  5. yaw取消,将旋转朝向运动打开,设置旋转速率为500设置弹簧臂摄像机

第二章

1
2
3
4
5
6
7
GAS,
Attribute(属性),
gameplay effects
gameplay tags
MVC 架构 处理UI
gameplay ABILITIES 技能
行为树

​ GE 属性初始化和UI显示等…

GamplayAbility 简称 GA,是UE引擎里的GAS内的功能组件,它的主要功能包括技能冷却时间(CD)和技能消耗的管理,同时也支持网络同步和实例支持。开发者可以在ActivateAbility事件中编写相关的技能逻辑,如角色动作、粒子效果以及角色数值的变动。根据技能是否施展成功,可以调用CommitAbility()或EndAbility()来结束技能。
————————————————

原文链接:https://blog.csdn.net/qq_30100043/article/details/137234914

第一节:添加接口

  1. 创建Interaction文件夹C++类EnemyInteraction接口类

    • EnemyInteraction头文件代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // Fill out your copyright notice in the Description page of Project Settings.

    #pragma once

    #include "CoreMinimal.h"
    #include "UObject/Interface.h"
    #include "EnemyInterface.generated.h"

    // This class does not need to be modified.
    UINTERFACE(MinimalAPI)
    class UEnemyInterface : public UInterface
    {
    GENERATED_BODY()
    };

    /**
    *
    */
    class GAS_API IEnemyInterface
    {
    GENERATED_BODY()

    // Add interface functions to this class. This is the class that will be inherited to implement this interface.
    public:
    //声明接口类
    virtual void HighightActor()=0;
    virtual void UnHighlightActor()=0;
    };

  2. 在怪物基类实现接口AuraEnemy.h

    • 头文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // Fill out your copyright notice in the Description page of Project Settings.

    #pragma once

    #include "CoreMinimal.h"
    #include "Character/AuraCharacterBase.h"
    #include "Interface/EnemyInterface.h"
    #include "AuraEnemy.generated.h"

    /**
    *
    */
    UCLASS() //继承接口类
    class GAS_API AAuraEnemy : public AAuraCharacterBase,public IEnemyInterface
    {
    GENERATED_BODY()
    public:
    //实现接口函数
    void HighightActor();
    void UnHighlightActor();
    };

    • 源文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // Fill out your copyright notice in the Description page of Project Settings.


    #include "Character/AuraEnemy.h"
    //实现接口函数
    void AAuraEnemy::HighightActor()
    {
    }

    void AAuraEnemy::UnHighlightActor()
    {
    }

UI

创建血量UI

  • 尺寸框控件-SizeBox_Root

  • 覆盖控件-Overlay_Root

  • 图片控件[背景]-Image_Background

  • 进度条控件

    • 样式-填充图=图片
    • 样式-填充图-改为图形填充
    • 百分比=1
    • 下至上
    • 外观-填充透明A=1
    • 样式-背景-透明度=0
  • 添加图片控件-比例

    • 更新玻璃背景
    • 设置填充大小

代码

用户控件基类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "AuraUserWidget.generated.h"

// 用户界面基类
UCLASS()
class AURADEMO_API UAuraUserWidget : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void SetWidgetController(UObject* InWidgetController);

UPROPERTY(BlueprintReadOnly)
TObjectPtr<UObject> WidgetController;
protected:
//事件
UFUNCTION(BlueprintImplementableEvent)
void WidgetControllerSet();
};

1
2
3
4
5
6
7
8
9
10
11
12
13
// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/Widget/AuraUserWidget.h"

void UAuraUserWidget::SetWidgetController(UObject* InWidgetController)
{
// 将传入的Widget控制器对象赋值给类成员变量WidgetController
WidgetController = InWidgetController;
// 调用WidgetControllerSet函数,通知已经设置了Widget控制器对象
WidgetControllerSet();
}

控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "AuraWidgetController.generated.h"

class UAttributeSet;
class UAbilitySystemComponent;
class UAbilitySystemComponent;

USTRUCT(BlueprintType)
struct FWidgetControllerParame
{
GENERATED_BODY()

FWidgetControllerParame(){};
FWidgetControllerParame(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* InAbiliASCtySystemComponent, UAttributeSet* AS)
: PlayerController(PC), PlayerState(PS), AbilitySystemComponent(InAbiliASCtySystemComponent), 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 AURADEMO_API UAuraWidgetController : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void SetWidgetControllerParams(const FWidgetControllerParame& WCParams);
virtual void BroadcastInitialValues();
virtual void BindCallbacksToDependencies();
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;
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/WidgetController/AuraWidgetController.h"

void UAuraWidgetController::SetWidgetControllerParams(const FWidgetControllerParame& WCParams)
{
PlayerController = WCParams.PlayerController;
PlayerState = WCParams.PlayerState;
AbilitySystemComponent = WCParams.AbilitySystemComponent;
AttributeSet = WCParams.AttributeSet;
}

void UAuraWidgetController::BroadcastInitialValues()
{
}

void UAuraWidgetController::BindCallbacksToDependencies()
{
}

控制器子类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UI/WidgetController/AuraWidgetController.h"
#include "OverlayWidgetController.generated.h"

struct FOnAttributeChangeData;
//生命值改变时发出通知
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealtChangedSignature, float, NewHealt);
//最大生命值改变时发出通知
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMaxHealtChangedSignature,float , NewMaxHealt);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnManaChangedSignature, float, NewMana);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnMaxManaChangedSignature,float , NewMaxMana);

// 覆盖层控制器子类
UCLASS(Blueprintable,BlueprintType)
class AURADEMO_API UOverlayWidgetController : public UAuraWidgetController
{
GENERATED_BODY()

public:
//当属性改变时发出通知
virtual void BroadcastInitialValues() override;
//当属性改变时绑定回调
virtual void BindCallbacksToDependencies() override;

//事件:生命值改变时发出
UPROPERTY(BlueprintAssignable, Category = "GAS|Attributes")
FOnHealtChangedSignature OnHealtChanged;

//事件:声明最大值改变时发出
UPROPERTY(BlueprintAssignable, Category = "GAS|Attributes")
FOnMaxHealtChangedSignature OnMaxHealtChanged;

UPROPERTY(BlueprintAssignable, Category = "GAS|Attributes")
FOnManaChangedSignature OnManaChanged;

UPROPERTY(BlueprintAssignable, Category = "GAS|Attributes")
FOnMaxManaChangedSignature OnMaxManaChanged;

protected:
// 生命值改变时发出
void HealthChanged(const FOnAttributeChangeData& Data) const;
// 最大生命值改变时发出
void MaxHealthChanged(const FOnAttributeChangeData& Data) const;

void ManaChanged(const FOnAttributeChangeData& Data) const;
void MaxManaChanged(const FOnAttributeChangeData& Data) const;

};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/WidgetController/OverlayWidgetController.h"
#include "AbilitySystem/AuraAttributeSet.h"

/*初始化属性时发出通知*/
void UOverlayWidgetController::BroadcastInitialValues()
{
Super::BroadcastInitialValues();
const UAuraAttributeSet* AuraAttributeSet = CastChecked<UAuraAttributeSet>(AttributeSet);
OnHealtChanged.Broadcast(AuraAttributeSet->GetHealth());
OnMaxHealtChanged.Broadcast(AuraAttributeSet->GetMaxHealth());
OnManaChanged.Broadcast(AuraAttributeSet->GetMana());
OnMaxManaChanged.Broadcast(AuraAttributeSet->GetMaxMana());

}

/*绑定属性回调*/
void UOverlayWidgetController::BindCallbacksToDependencies()
{
Super::BindCallbacksToDependencies();
const UAuraAttributeSet* AuraAttributeSet = CastChecked<UAuraAttributeSet>(AttributeSet);
//绑定生命值回调
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
AuraAttributeSet->GetHealthAttribute()).AddUObject(this, &UOverlayWidgetController::HealthChanged);
//绑定最大生命值回调
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
AuraAttributeSet->GetMaxHealthAttribute()).AddUObject(this, &UOverlayWidgetController::MaxHealthChanged);
//绑定法力值回调
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
AuraAttributeSet->GetManaAttribute()).AddUObject(this, &UOverlayWidgetController::ManaChanged);
//绑定最大法力值回调
AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(
AuraAttributeSet->GetMaxManaAttribute()).AddUObject(this, &UOverlayWidgetController::MaxManaChanged);
}


/*当属性改变时发出通知*/
void UOverlayWidgetController::HealthChanged(const FOnAttributeChangeData& Data) const
{
OnHealtChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::MaxHealthChanged(const FOnAttributeChangeData& Data) const
{
OnMaxHealtChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::ManaChanged(const FOnAttributeChangeData& Data) const
{
OnManaChanged.Broadcast(Data.NewValue);
}

void UOverlayWidgetController::MaxManaChanged(const FOnAttributeChangeData& Data) const
{
OnMaxManaChanged.Broadcast(Data.NewValue);
}

HUD

  • 事件基本在这发出和绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "UI/Widget/AuraUserWidget.h"
#include "AuraHUD.generated.h"

class UOverlayWidgetController;
class UAuraUserWidget;
class UAttributeSet;
struct FWidgetControllerParame;

//玩家HUD,负责创建覆盖控件和绑定控制器
UCLASS(Blueprintable, BlueprintType)
class AURADEMO_API AAuraHUD : public AHUD
{
GENERATED_BODY()
public:
//覆盖控件
UPROPERTY()
TObjectPtr<UAuraUserWidget> OverlayWidget;

//通过结构体创建或者获取控制器
UOverlayWidgetController *GetOverlayWidgetController(const FWidgetControllerParame& WCParams);

// 初始化控制器数据
UFUNCTION(BlueprintCallable)
void InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS);
private:
//覆盖控件类引用
UPROPERTY(EditAnywhere)
TSubclassOf<UAuraUserWidget> OverlayWidgetClass;

//控制器实例指针
UPROPERTY()
TObjectPtr<UOverlayWidgetController> OverlayWidgetController;

//控制器类引用
UPROPERTY(EditAnywhere)
TSubclassOf<UOverlayWidgetController> OverlayWidgetControllerClass;
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/HUD/AuraHUD.h"
#include "UI/WidgetController/OverlayWidgetController.h"


UOverlayWidgetController* AAuraHUD::GetOverlayWidgetController(const FWidgetControllerParame& WCParams)
{
if(OverlayWidgetController == nullptr)
{
OverlayWidgetController = NewObject<UOverlayWidgetController>(this, OverlayWidgetControllerClass);
OverlayWidgetController->SetWidgetControllerParams(WCParams);
OverlayWidgetController->BindCallbacksToDependencies();
}
return OverlayWidgetController;
}

void AAuraHUD::InitOverlay(APlayerController* PC, APlayerState* PS, UAbilitySystemComponent* ASC, UAttributeSet* AS)
{
//判断控制器类类引用和状态UI类引用是否有效
checkf(OverlayWidgetClass, TEXT("OverlayWidgetClass is nullptr"))
checkf(OverlayWidgetControllerClass, TEXT("OverlayWidgetControllerClass is nullptr"))

//创建覆盖控件
UUserWidget * Widget = CreateWidget<UUserWidget>(GetWorld(), OverlayWidgetClass);
OverlayWidget= Cast<UAuraUserWidget>(Widget);

//创建结构体并将参数构造
const FWidgetControllerParame FWidgetControllerParame = {PC, PS, ASC, AS};
//获取OverlayWidgetController
UOverlayWidgetController * WidgetController = GetOverlayWidgetController(FWidgetControllerParame);

//设置覆盖控件的控制器,发出事件
OverlayWidget->SetWidgetController(WidgetController);
WidgetController->BroadcastInitialValues();

//添加到视口
Widget->AddToViewport();
}


AuraCharacter.cpp*********************************************为初始化的地方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Fill out your copyright notice in the Description page of Project Settings.


#include "Character/AuraCharacter.h"
#include "AbilitySystem/AuraAbilitySystemComponent.h"
#include "Player/AuraPlayerController.h"
#include "Player/AuraPlayerState.h"
#include "UI/HUD/AuraHUD.h"

void AAuraCharacter::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
InitAbilityActorInfo();
}

void AAuraCharacter::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
InitAbilityActorInfo();
}

void AAuraCharacter::InitAbilityActorInfo()
{
/*初始化玩家角色能力系统和属性*/
AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
check(AuraPlayerState);
AuraPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(AuraPlayerState, this);
Cast<UAuraAbilitySystemComponent>(AuraPlayerState->GetAbilitySystemComponent())->AbilityActorInfoSet();//绑定委托,未实现
AbilitySystemComponent = AuraPlayerState->GetAbilitySystemComponent();
AttributeSet = AuraPlayerState->GetAttributeSet();

//初始化Mvc控制器*********************************************
if(AAuraPlayerController* AuraPlayerController = Cast<AAuraPlayerController>(GetController()))
{
if(AAuraHUD* AuraHUD = Cast<AAuraHUD>(AuraPlayerController->GetHUD()))
{
AuraHUD->InitOverlay(AuraPlayerController, AuraPlayerState, AbilitySystemComponent, AttributeSet);
}
}
}

配置GAS

第一节:添加CPP类和声明

  • 打开插件添加UAbilitySystemComponent的c++类

  • 添加UAttributeSet的c++类

  • 在玩家基类添加前向声明

  • class UAbilitySystemComponent;
    class UAttributeSet;
    
    1
    2
    3
    4
    5
    6
    7
    3. 玩家基类添加IAbilitySystemInterface接口
    4. 声明IAbilitySystemInterface和UAttributeSet对象

    5. 实现接口函数virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override

    ```cpp
    return IAbilitySystemInterface实例
  1. 添加APlayerState c++类,将角色声明的UAbilitySystemComponent也复制一份进去,前向声明也需要

第二节:创建实例

  • 玩家的需要在AAuraPlayerState构造函数上实例
1
2
3
4
5
6
7
8
9
10
11
12
13
AAuraPlayerState::AAuraPlayerState()
{
AbilitySystemComponent = CreateDefaultSubobject<UAuraAbilitySystemComponent>("AbilitySystemComponent");
AbilitySystemComponent->SetIsReplicated(true);

//设置网络同步 同步技能冷却事件等
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);

AttributeSet = CreateDefaultSubobject<UAuraAttributeSet>("AttributeSet");

//这段C++代码是Unreal Engine中的一部分,用于设置一个玩家状态(AAuraPlayerState)的网络更新频率
NetUpdateFrequency=100.f;
}
  • 怪物的需要在怪物基类构造函数实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ACharacterEnemy::ACharacterEnemy()
{
//基类AbilitySystemComponent属性
//创建默认子对象:
//设置属性复制:
//设定效果复制模式:
AbilitySystemComponent = CreateDefaultSubobject<UAuraAbilitySystemComponent>("AbilitySystemComponent");
AbilitySystemComponent->SetIsReplicated(true);

//设置网络同步,不同步技能冷却事件等
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);

//这段代码的作用是创建并初始化一个默认的属性集(UAuraAttributeSet)作为该类的一个子对象。
AttributeSet = CreateDefaultSubobject<UAuraAttributeSet>("AttributeSet");
}

第三节:处理网络同步,如上注释

  • 设置怪物和玩家网络同步AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal); 带面见上边

  • 设置怪物代理,在BeginPlay函数下

    1
    2
    3
    4
    5
    6
    7
    void ACharacterEnemy::BeginPlay()
    {
    Super::BeginPlay();
    check(AbilitySystemComponent)
    //初始化属性? 怪物自己持有,怪物自己代理
    AbilitySystemComponent->InitAbilityActorInfo(this,this);
    }
  • 设置玩家代理,在玩家基类下声明InitAbilityActorInfo()和重写两个虚函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    virtual void PossessedBy(AController* NewController) override;
    void ACharacterBase::PossessedBy(AController* NewController)
    {
    //服务器
    Super::PossessedBy(NewController);
    InitAbilityActorInfo();
    }
    virtual void OnRep_PlayerState() override;
    void ACharacterBase::OnRep_PlayerState()
    {
    //客户端
    Super::OnRep_PlayerState();
    InitAbilityActorInfo();
    }

    实现 自己持有,代理玩家

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void ACharacterBase::InitAbilityActorInfo()
    {
    AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
    check(AuraPlayerState);
    AuraPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(AuraPlayerState, this);
    Cast<UAuraAbilitySystemComponent>(AuraPlayerState->GetAbilitySystemComponent())->AbilityActorInfoSet(); //漏写
    AbilitySystemComponent = AuraPlayerState->GetAbilitySystemComponent();
    AttributeSet = AuraPlayerState->GetAttributeSet();
    }

第四节:属性声明

  • 属性声明打开UAttributeSet

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    // Fill out your copyright notice in the Description page of Project Settings.

    /*在虚幻引擎5(UE5)中,UAttributeSet 是一个用于存储和管理游戏中实体(如角色、敌人等)属性的数据结构。
    *它是基于 Unreal 的属性系统(Attribute System),该系统设计用于高效地处理和同步这些属性,尤其是在网络环境中。
    UAttributeSet 类通常作为蓝图类或者C++类的一个成员变量来使用,
    它允许开发者定义一系列属性,如生命值(Health)、魔法值(Mana)、力量(Strength)等,并提供了访问和修改这些属性值的接口。
    这些属性可以被标记为需要在网络上同步,以便于多人游戏中的状态同步。
    要创建自定义的 UAttributeSet 类,你需要继承自 UAttributeSet 并定义你的属性。
    这通常涉及到使用 UPROPERTY() 宏来声明属性,并可能使用 UPROPERTY(Replicated) 来确保它们在网络上的客户端间正确同步。
    此外,你可能还需要实现一些逻辑来处理属性的变化,例如当生命值减少到零时触发死亡事件*/

    #pragma once

    #include "CoreMinimal.h"
    #include "AttributeSet.h"
    #include "AbilitySystemComponent.h"
    #include "AuraAttributeSet.generated.h"

    //设置访问宏
    //在虚幻引擎(Unreal Engine)的C++编程中,
    //ATTRIBUTE_ACCESSORS 是一个宏,用于自动生成属性(Attribute)的存取器(Getter 和 Setter)函数。
    //这个宏常用于UAttributeSet子类中,以便于更便捷地操作游戏属性,如角色的生命值、能量、攻击力等
    //使用 ATTRIBUTE_ACCESSORS 宏可以减少重复代码,让代码更加简洁且易于维护。
    //它通常与属性声明一起使用,自动为你生成相应的函数来读取和设置 FGameplayAttributeData 中的属性值。
    #define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
    GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
    GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
    GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
    GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
    /**
    *
    */
    UCLASS()
    class GASDEMO_API UAuraAttributeSet : public UAttributeSet
    {
    GENERATED_BODY()

    public:
    UAuraAttributeSet();
    virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

    /*属性声明*/
    //生命值
    UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = "Primary Attributes")
    FGameplayAttributeData Health; //GameplayAttributeData 结构体是用来存储游戏属性的具体数值及其相关元数据的
    ATTRIBUTE_ACCESSORS(UAuraAttributeSet, Health);
    //最大生命值
    UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth, Category = "Primary Attributes")
    FGameplayAttributeData MaxHealth;
    ATTRIBUTE_ACCESSORS(UAuraAttributeSet, MaxHealth);
    //魔法值
    UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Mana, Category = "Primary Attributes")
    FGameplayAttributeData Mana;
    ATTRIBUTE_ACCESSORS(UAuraAttributeSet, Mana);
    //最大魔法值
    UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxMana, Category = "Primary Attributes")
    FGameplayAttributeData MaxMana;
    ATTRIBUTE_ACCESSORS(UAuraAttributeSet, MaxMana);

    /*属性函数*/
    //在你的代码中,OnRep_Health 是一个 Unreal Engine 中的特殊函数,用于处理网络复制(replication)过程中属性发生变化的情况。
    //当一个具有 replicated 属性的变量(在这个例子中似乎是Health,尽管它没有直接展示出来)在服务器上发生改变时,
    //此函数会在所有相关的客户端上被调用来反映这一变化,确保所有玩家看到的游戏状态是一致的
    UFUNCTION()
    void OnRep_Health(const FGameplayAttributeData& OldHealth) const;

    UFUNCTION()
    void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const;

    UFUNCTION()
    void OnRep_Mana(const FGameplayAttributeData& OldMana) const;

    UFUNCTION()
    void OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const;
    };

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    // Fill out your copyright notice in the Description page of Project Settings.


    #include "AbilitySystem/AuraAttributeSet.h"
    #include "AbilitySystemComponent.h"
    #include "Net/UnrealNetwork.h"

    UAuraAttributeSet::UAuraAttributeSet()
    {
    //初始化属性
    InitHealth(100.f);
    InitMaxHealth(100.f);
    InitMana(50.f);
    InitMaxMana(50.f);
    }

    void UAuraAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
    {
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    /*注册属性*/
    //在Unreal Engine网络编程中,DOREPLIFETIME_CONDITION_NOTIFY 宏用于控制特定Actor或ActorComponent属性的生命周期管理,
    //特别是关于其在网络中的复制行为。
    //这个宏帮助你定义哪些属性应该在网络上同步,以及在什么条件下同步,同时还能在属性发生变化时触发自定义的通知回调。
    //UAuraAttributeSet: 这里指定了属性所属的类,即属性集类,它通常继承自 UAttributeSet 并用于存储游戏角色的各种属性。
    //Health: 指定要管理其网络生命周期的属性名。在这个上下文中,Health 是玩家或角色的一个关键属性,需要在网络环境中实时同步
    //COND_None: 这是同步条件。COND_None 表示没有特别的条件限制,意味着无论何时只要属性值改变就会尝试进行同步。
    //在其他情况下,可能会有比如仅当玩家拥有控制器 (COND_OwnerOnly) 或者仅当属性在特定范围内改变 (COND_SkipIfNotDirty) 等条件。
    //EPNOTIFY_Always: 这决定何时触发通知回调。REPNOTIFY_Always 表明每次属性值改变时,不论是在服务器还是客户端,都会调用通知回调函数(通常是 OnRep_Health)。
    //这意味着每次 Health 值发生变动,即使变动后的值与旧值相同,也会触发通知。
    DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, Health, COND_None, REPNOTIFY_Always);
    DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
    DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, Mana, COND_None, REPNOTIFY_Always);
    DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, MaxMana, COND_None, REPNOTIFY_Always);
    }

    /*属性函数实现*/
    void UAuraAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const
    {
    //宏的作用:此宏会在编译时期生成必要的代码来自动调用 OnRep_Health 函数,当 Health 属性的值在服务器上发生变化时。
    //它确保了当属性的值由于服务器端的更新而有所不同时,所有相关的客户端都会得到通知,并执行相应的 OnRep_Health 回调。
    //UAuraAttributeSet:这是属性集类的名称,即定义属性和复制逻辑的类。
    //Health:这是你要为其添加复制通知的属性名称。这意味着每当 Health 属性的值发生变化时,框架都会自动处理网络同步。
    //ldHealth:这是传递给 OnRep_Health 回调函数的参数名称,表示属性更改前的旧值。这允许你在回调中比较新旧值并做出相应处理
    GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, Health, OldHealth);
    }

    void UAuraAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const
    {
    GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, MaxHealth, OldMaxHealth);
    }

    void UAuraAttributeSet::OnRep_Mana(const FGameplayAttributeData& OldMana) const
    {
    GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, Mana, OldMana);
    }

    void UAuraAttributeSet::OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const
    {
    GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, MaxMana, OldMaxMana);
    }



项目

代码文件夹

文件夹 中文
Ability System 能力系统
Actor 演员
AI 人工智能
Anim Notifies 动画通知
Characte 角色
checkpoint 检查站,存档点
Game 游戏
Input 输入
MainMenu 主菜单
Player 玩家
Spawn Volumes 产卵量
UI UI

Ability System

  • Abilities 技能
  • AbilityTasks 鼠标
描述 继承
AuraGameplayAbility 该C++类定义了一个游戏中的技能组件 UGameplayAbility
UAuraDamageGameplayAbility //该C++类定义了一个名为UAuraDamageGameplayAbility的游戏能力,继承自UAuraGameplayAbility。主要功能包括: // CauseDamage:对目标造成伤害。 // MakeDamageEffectParamsFromClassDefaults:根据类默认值生成伤害效果参数。 // GetDamageAtLevel:获取当前等级下的伤害值。 // 包含多个编辑器属性,如伤害类型、伤害值、减益效果等,用于配置伤害行为 AuraGameplayAbility
UAuraPassiveAbility // 该C++类定义了一个名为UAuraPassiveAbility的被动技能基类,继承自UAuraGameplayAbility。主要包含两个函数: // ActivateAbility:重写父类的激活能力函数,用于初始化被动技能。 // ReceiveDeactivate:接收并处理被动技能被移除或失效的情况,参数为一个游戏标签 AuraGameplayAbility
UAuraSummonAbility // 该C++类UAuraSummonAbility继承自UAuraGameplayAbility,主要用于游戏中的召唤功能。主要功能如下: // GetSpawnLocations:返回一系列用于召唤的位置向量。 // GetRandomMinionClass:返回一个随机的召唤物(小兵)类。 // NumMinions:设置需要召唤的小兵数量,默认为5。 // MinionClasses:存储可召唤的小兵类列表。 // MinSpawnDistance:设置最小召唤距离,默认为50单位。 // MaxSpawnDistance:设置最大召唤距离,默认为250单位。 // SpawnSpread:设置召唤物分布的角度范围,默认为90度。 AuraGameplayAbility
UArcaneShards //该C++类UArcaneShards继承自UAuraDamageGameplayAbility,主要用于游戏中的某种伤害能力。它包含: // 虚拟函数GetDescription,返回技能描述。 // 虚拟函数GetNextLevelDescription,返回升级后的技能描述。 // 成员变量MaxNumShards,存储最大碎片数量,默认为11。 UAuraDamageGameplayAbility
UAuraBeamSpell // 该C++类UAuraBeamSpell继承自UAuraDamageGameplayAbility,主要用于实现游戏中的一种光束法术能力。其主要功能包括: // 存储鼠标点击信息(位置和演员)。 // 追踪首个目标的位置。 // 存储额外的目标列表。 // 处理主要目标和额外目标死亡事件。 // 其中成员变量定义了鼠标点击位置、点击到的演员、拥有者控制器及角色等信息,并设置了最大可追踪目标数量为5。 UAuraDamageGameplayAbility
UAuraFireBlast // 该C++类UAuraFireBlast继承自UAuraDamageGameplayAbility,主要功能包括: // 生成火球描述文本(GetDescription和GetNextLevelDescription方法)。 // 召唤多个火球(通过SpawnFireBalls方法)。 // 定义了火球数量(NumFireBalls属性,默认为12)和火球类(FireBallClass属性) UAuraDamageGameplayAbility
UAuraMeleeAttack UAuraDamageGameplayAbility
UElectrocute // 该C++类UElectrocute继承自UAuraBeamSpell,主要用于实现游戏中的“电击”法术效果。其功能包括: // 重写GetDescription方法,用于获取当前等级的法术描述。 // 重写GetNextLevelDescription方法,用于获取升级后的法术描述。 UAuraBeamSpell
UAuraFireBolt UAuraProjectileSpell
UElectrocute UAuraBeamSpell

graph TD;
A–>B;
A–>C;
B–>D;

UI MVC架构

1
2
3
4
需要的代码
小部件控制器 负责操作数据
小部件 负责显示属性
HUD 负责绘制小部件
  • HUD
  • ViewModel MVVM
  • Widget 控件基类
  • WidgetController 小部件控制

Ability System 技能管理

AuraSummonAbility 怪物召唤
ProjectileSpell 投射物
UAuraBeamSpell 光束
Electrocute:继承UArcaneShards 雷电技能
UArcaneShards 水晶碎片
UAuraFireBlast 多火球
UAuraFireBolt:继承投射物ProjectileSpell 火球
UAuraGameplayAbility 基类
UAuraPassiveAbility 被动
UAuraDamageGameplayAbility 处理伤害

Actor 技能实例

AuraEffectActor 火焰
AuraEnemySpawnPoint 敌人生成
Enemy Spawn Volume 敌人生成
Fire Ball 火球
AuraProjectile
Magic Circle 魔术圈
Point Collection 点集合

蓝图

ACS配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class GasDemo : ModuleRules
{
public GasDemo(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore","EnhancedInput", "GameplayAbilities" });

PrivateDependencyModuleNames.AddRange(new string[] { "GameplayTags", "GameplayTasks", "NavigationSystem", "Niagara", "AIModule" });

// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });

// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");

// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}

属性配置

UAttributeSet配置

showdebug abilitysystem 显示属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "MyAttributeSet.generated.h"

/**
*
*/
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)

UCLASS()
class JIANGBAODEMO_API UMyAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:

UMyAttributeSet();
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category = "Primary Attributes")
FGameplayAttributeData Health;
ATTRIBUTE_ACCESSORS(UMyAttributeSet, Health);
//最大生命值
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth, Category = "Primary Attributes")
FGameplayAttributeData MaxHealth;
ATTRIBUTE_ACCESSORS(UMyAttributeSet, MaxHealth);

UFUNCTION()
void OnRep_Health(const FGameplayAttributeData& OldHealth) const;

UFUNCTION()
void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Fill out your copyright notice in the Description page of Project Settings.


#include "MyAttributeSet.h"
#include "AbilitySystemComponent.h"
#include "Net/UnrealNetwork.h"

UMyAttributeSet::UMyAttributeSet()
{
InitHealth(100.f);
InitMaxHealth(100.f);
}

void UMyAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, Health, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UMyAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
}

void UMyAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UMyAttributeSet, Health, OldHealth);
}

void UMyAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UMyAttributeSet, MaxHealth, OldMaxHealth);
}

PlayerState配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#pragma once

#include "CoreMinimal.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/PlayerState.h"
#include "AuraPlayerState.generated.h"

class UAbilitySystemComponent;
class UAttributeSet;
/**
*
*/
UCLASS()
class GASDEMO_API AAuraPlayerState : public APlayerState,public IAbilitySystemInterface
{
GENERATED_BODY()
public:
AAuraPlayerState();
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
UAttributeSet* GetAttributeSet() const { return AttributeSet; }
protected:

UPROPERTY()
//指向UAbilitySystemComponent的智能指针,用于管理玩家的能力和效果。
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;

UPROPERTY()
//指向UAttributeSet的智能指针,用于存储玩家的属性值,如生命值、魔法值等
TObjectPtr<UAttributeSet> AttributeSet;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "Player/AuraPlayerState.h"
#include "AbilitySystem/AuraAbilitySystemComponent.h"
#include "AbilitySystem/AuraAttributeSet.h"

AAuraPlayerState::AAuraPlayerState()
{
AbilitySystemComponent = CreateDefaultSubobject<UAuraAbilitySystemComponent>("AbilitySystemComponent");
AbilitySystemComponent->SetIsReplicated(true);
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);

AttributeSet = CreateDefaultSubobject<UAuraAttributeSet>("AttributeSet");

//这段C++代码是Unreal Engine中的一部分,用于设置一个玩家状态(AAuraPlayerState)的网络更新频率
NetUpdateFrequency=100.f;
}
//接口继承的方法,返回AbilitySystemComponent
UAbilitySystemComponent* AAuraPlayerState::GetAbilitySystemComponent() const
{
return AbilitySystemComponent;
}

玩家配置

  • 基类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "AbilitySystemInterface.h"
#include "AuraCharacterBase.generated.h"

class UAbilitySystemComponent;
class UAttributeSet;

UCLASS()
class AURADEMO_API AAuraCharacterBase : public ACharacter,public IAbilitySystemInterface
{
GENERATED_BODY()

public:
AAuraCharacterBase();

virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
UAttributeSet* GetAttributeSet() const { return AttributeSet; };

protected:
virtual void BeginPlay() override;

/*UAbilitySystemComponent对象*/
UPROPERTY()
TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
/*UAttributeSet对象*/
UPROPERTY()
TObjectPtr<UAttributeSet> AttributeSet;
};
1
2
3
4
UAbilitySystemComponent* AAuraCharacterBase::GetAbilitySystemComponent() const
{
return AbilitySystemComponent;
}
  • 子类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#pragma once

#include "CoreMinimal.h"
#include "AuraCharacterBase.h"
#include "AuraCharacter.generated.h"

UCLASS()
class AURADEMO_API AAuraCharacter : public AAuraCharacterBase
{
GENERATED_BODY()
public:
virtual void PossessedBy(AController* NewController) override;
//网络同步相关
virtual void OnRep_PlayerState() override;
private:
void InitAbilityActorInfo();

};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "Character/AuraCharacter.h"
#include "AbilitySystem/AuraAbilitySystemComponent.h"
#include "Player/AuraPlayerState.h"

void AAuraCharacter::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
InitAbilityActorInfo();
}

void AAuraCharacter::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
InitAbilityActorInfo();
}

void AAuraCharacter::InitAbilityActorInfo()
{
/*初始化玩家角色能力系统和属性*/
AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
check(AuraPlayerState);
//玩家状态对玩家角色施加?
AuraPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(AuraPlayerState, this); //如果是怪物则AuraPlayerState改为this
Cast<UAuraAbilitySystemComponent>(AuraPlayerState->GetAbilitySystemComponent())->AbilityActorInfoSet();//绑定委托,未实现
AbilitySystemComponent = AuraPlayerState->GetAbilitySystemComponent();
AttributeSet = AuraPlayerState->GetAttributeSet();
}

添加和删除

  • 添加
1
2
AbilitySystemComponent->SpawnedAttributes.AddUnique(WeaponAttributeSetPointer);
AbilitySystemComponent->ForceReplication();
  • 删除
1
2
AbilitySystemComponent->SpawnedAttributes.Remove(WeaponAttributeSetPointer);
AbilitySystemComponent->ForceReplication();

能力(Ability)

GA一般要做的事

  • 设置GA的Tag、CD、Cost等属性。

  • 获取必要信息,主要通过Get Actor Info。如果是通过Event调用的GA(使用Activate Ability From Event节点作为输入),还可以通过Gameplay Event Data获取。

  • 编写逻辑,如播放动画、应用GE、应用冲量等。

  • 一定不要忘了EndAbility。

    标签(Tags)

    • 能力标签(Ability Tags)
    • 取消带标签的能力(Cancel abilities with tag)
    • 锁定带标签的能力(vlock [应为“lock”的误写] abilities with tag)
    • 激活拥有的标签(activation owned tags)
    • 激活被阻止的标签(activation blocked tags)
    • 源所需标签(source required tags)
    • 源被阻止的标签(source blocked tags)
    • 目标所需标签(target required tags)
    • 目标被阻止的标签(target blocked tags)

    输入(Input)

    • 直接复制输入(Replicate Input Directly)

    高级(Advanced)

    • 复制策略(ReplicationPolicy)
    • 实例化策略(Instancing Policy)
    • 服务器尊重远程能力取消(Server Respects Remote Ability Cancellation)
    • 重新触发实例化能力(Retrigger Instanced Ability)
    • 网络执行策略(Net Execution Policy)
    • 网络安全策略(Net Security Policy)

    成本(Costs)

    • 成本游戏效果类(Cost Gameplay Effect Class)

    触发器(Triggers)

    • 能力触发器(Ability Triggers)

    冷却时间(Cooldowns)

    • 冷却时间游戏效果类(Cooldown Gameplay Effect Class)

申请GE实现扣血

1
2
applygameplayeffecttoowner
playmontageandwai

GE

  • 编辑器状态文本 (Editor Status Text)
  • 持续时间 (Duration)
    • Instant 立即生效
    • Infinite 永久生效
    • Period 周期内生效
  • 游戏效果 (Gameplay Effect)
    • 组件 (Components)
    • 修饰符 (Modifiers)
    • 执行 (Executions)
  • 游戏提示 (Gameplay Cues)
    • Require Modifier Success to Trigger Cues 需要修饰符成功才能触发提示
    • Suppress Stacking Cues 抑制叠加提示
    • Gameplay Cues 游戏提示
  • 叠加 (Stacking)
    • Stacking Type 叠加类型

蓝图文件夹

AbilitySystem 能力系统

  • 定义能力系统,包括GE,GA,GC和属性数据

Aura

  • Abilities 能力 里边的蓝图好像是魔法阵的
  • Effects 效果 用于初始化数据的GE类

data 数据表格和数据资产

Enemy 怪物的技能和能力

GameplayCueNotifies 特效和音效等

GameplayTags 游戏标签数据表

Actor 演员(用于当玩家碰撞物品时将效果应用到玩家身上)

Area 地火演员和GE

Crystal 水晶

FadeActor 建筑蓝图,继承接口,识别可点击点?

FlamePillar 火焰柱

Potion 药水

Test Actor 测试的演员

AI

AnimNotifies 动画通知

Character 角色 (除了玩家怪物都没用蓝图节点)

Checkpoint 检查点 (用了蓝图)

Game 游戏 (游戏单例类,包含存储)

Input 输入 (输入映射配置)

Player 玩家 (玩家控制器和玩家状态蓝图)

SpawnVolumes 产卵量

UI 界面

data 数据表

HUD

ViewModel 数据模型

WidgetController 小部件控制器 继承者UObject