虚幻引擎UE5 GAS开发RPG游戏-02 设置英雄角色-12 游戏能力系统

部署运行你感兴趣的模型镜像

目标:使用GAS制作武器,并赋予能力

流程:

Gameplay AbilitySystem

1.启用插件:GameplayAbilities

2.创建类

3.尝试编译,遇到报错,原因是在Source/Warrior/Warrior.Build.cs里缺少GameplayTasks模块依赖

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class Warrior : ModuleRules
{
	public Warrior(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[]
		{
			"Core", 
			"CoreUObject",
			"Engine",
			"InputCore", 
			"EnhancedInput",
			"GameplayTags",
			"GameplayTasks"
		});

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// 如果您使用的是Slate UI,请取消注释
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// 如果您正在使用在线功能,请取消注释
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

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

再编译,成功!

4.在角色基类里,添加能力系统组件和属性集:

protected:
	
#pragma region AbilitySystem
	//能力系统组件
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AbilitySystem")
	UWarriorAbilitySystemComponent* WarriorAbilitySystemComponent;

	// 属性集
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AbilitySystem")
	UWarriorAttributeSet* WarriorAttributeSet;
	
#pragma endregion

创建他们的getter函数:

public:
	
#pragma region getter
	FORCEINLINE UWarriorAbilitySystemComponent* GetWarriorAbilitySystemComponent() const { return WarriorAbilitySystemComponent; }

	FORCEINLINE UWarriorAttributeSet* GetWarriorAttribute() const { return WarriorAttributeSet; }

#pragma endregion

这段代码展示了C++中使用#pragma region指令来组织getter方法的典型用法。主要特点包括:

  1. #pragma region getter#pragma endregion这对指令用于将相关代码折叠为一个可命名的逻辑区域,方便在IDE中管理代码结构。

  2. 两个getter方法都使用了FORCEINLINE宏,这通常表示编译器会强制内联这些简单的方法调用以提高性能。

  3. 方法返回的是指向组件对象的指针:

    • GetWarriorAbilitySystemComponent()返回UWarriorAbilitySystemComponent类型指针
    • GetWarriorAttribute()返回UWarriorAttributeSet类型指针
  4. 两个方法都被声明为const,表示它们不会修改类的成员变量。

5.在构造函数里构造这两个组件:

// 构造函数
AWarriorBaseCharacter::AWarriorBaseCharacter()
{
 	// 将此字符设置为每帧调用Tick()。如果你不需要它,你可以关闭它来提高性能。
	PrimaryActorTick.bCanEverTick = false;
	PrimaryActorTick.bStartWithTickEnabled = false;

	/** 图元是否接收贴花。 */
	GetMesh()->bReceivesDecals = false;

	//将能力系统组件添加到角色
	WarriorAbilitySystemComponent = CreateDefaultSubobject<UWarriorAbilitySystemComponent>(TEXT("WarriorAbilitySystemComponent"));

	//将属性集添加到角色
	WarriorAttributeSet = CreateDefaultSubobject<UWarriorAttributeSet>(TEXT("WarriorAttributeSet"));
}

6.重写PossessedBy函数:

//~Begin Apawn Interface.
	virtual void PossessedBy(AController* NewController) override;
//~ End APawn Interface

这段代码展示了一个典型的Unreal Engine虚函数重写声明,属于APawn类的核心接口实现。主要特点如下:

  1. 函数声明使用了virtualoverride关键字:

    • virtual表明这是一个虚函数,支持运行时多态
    • override显式声明这是对父类虚函数的重写
  2. PossessedBy是APawn的关键方法:

    • 当Controller(玩家或AI)获得该Pawn控制权时触发
    • 参数NewController指向新的控制者对象
  3. 注释标记//~Begin/End APawn Interface

    • 这是Unreal Engine特有的代码组织方式
    • 用于标识APawn接口的实现区域

这种设计模式体现了Unreal Engine中常见的多态实现方式,通过虚函数机制让派生类可以自定义被控制时的行为。在游戏逻辑中,当角色被玩家或AI控制时,这个函数会被自动调用以执行必要的初始化操作。

7.实现:

void AWarriorBaseCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);
	if (WarriorAbilitySystemComponent)
	{
		WarriorAbilitySystemComponent->InitAbilityActorInfo(this, this);
	}
}

这段代码是Unreal Engine中角色被控制器(Controller)控制时的核心逻辑实现,主要涉及GAS(Gameplay Ability System)系统的初始化流程。其关键点包括:

  1. 继承调用‌:

    • 首先调用父类的PossessedBy方法,确保基础控制逻辑正常执行
    • Super::是Unreal Engine中调用父类方法的标准语法
  2. GAS系统初始化‌:

    • 检查WarriorAbilitySystemComponent指针有效性
    • 调用InitAbilityActorInfo初始化能力系统与角色的关联关系
    • 参数传递this指针两次,分别代表拥有者(Owner)和化身(Avatar)
  3. 多态实现‌:

    • 通过虚函数重写机制实现控制器获取时的自定义行为
    • 典型的运行时多态应用场景

该函数通常在以下情况被调用:

  • 玩家角色生成后被玩家控制器控制
  • AI角色被AIController接管时
  • 网络游戏中角色控制权转移时

对于玩家角色,通常会在以下时机调用InitAbilityActorInfo:

  • 服务器端:在Pawn的PossessedBy方法中
  • 客户端:在OnRep_PlayerState方法中
  • NPC角色:在BeginPlay中初始化

8.继承接口:

class WARRIOR_API AWarriorBaseCharacter : public ACharacter, public IAbilitySystemInterface

重写接口函数:

	//~Begin IAbilitySystemInterface Interface.
	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
	//~ End IAbilitySystemInterface Interface
	
UAbilitySystemComponent* AWarriorBaseCharacter::GetAbilitySystemComponent() const
{
	return WarriorAbilitySystemComponent;
}

源代码:

Source/Warrior/Public/Characters/WarriorBaseCharacter.h:

// Copyright @ ChenChao

#pragma once

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

#include "WarriorBaseCharacter.generated.h"

class UWarriorAttributeSet;
class UWarriorAbilitySystemComponent;

UCLASS()
class WARRIOR_API AWarriorBaseCharacter : public ACharacter, public IAbilitySystemInterface
{
	GENERATED_BODY()

public:
	// 设置此角色属性的默认值
	AWarriorBaseCharacter();

	//~Begin IAbilitySystemInterface Interface.
	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
	//~ End IAbilitySystemInterface Interface
	
protected:

	//~Begin Apawn Interface.
	virtual void PossessedBy(AController* NewController) override;	//当Controller(玩家或AI)获得该Pawn控制权时触发
	//~ End APawn Interface
	
#pragma region AbilitySystem
	//能力系统组件
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AbilitySystem")
	UWarriorAbilitySystemComponent* WarriorAbilitySystemComponent;

	// 属性集
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AbilitySystem")
	UWarriorAttributeSet* WarriorAttributeSet;
	
#pragma endregion

public:
	
#pragma region getter
	FORCEINLINE UWarriorAbilitySystemComponent* GetWarriorAbilitySystemComponent() const { return WarriorAbilitySystemComponent; }

	FORCEINLINE UWarriorAttributeSet* GetWarriorAttribute() const { return WarriorAttributeSet; }

#pragma endregion

	
};

Source/Warrior/Private/Characters/WarriorBaseCharacter.cpp:

// Copyright @ ChenChao



#include "Characters/WarriorBaseCharacter.h"

#include "WarriorDebugHelper.h"
#include "AbilitySystem/WarriorAbilitySystemComponent.h"
#include "AbilitySystem/WarriorAttributeSet.h"

// 构造函数
AWarriorBaseCharacter::AWarriorBaseCharacter()
{
 	// 将此字符设置为每帧调用Tick()。如果你不需要它,你可以关闭它来提高性能。
	PrimaryActorTick.bCanEverTick = false;
	PrimaryActorTick.bStartWithTickEnabled = false;

	/** 图元是否接收贴花。 */
	GetMesh()->bReceivesDecals = false;

	//将能力系统组件添加到角色
	WarriorAbilitySystemComponent = CreateDefaultSubobject<UWarriorAbilitySystemComponent>(TEXT("WarriorAbilitySystemComponent"));

	//将属性集添加到角色
	WarriorAttributeSet = CreateDefaultSubobject<UWarriorAttributeSet>(TEXT("WarriorAttributeSet"));
}

UAbilitySystemComponent* AWarriorBaseCharacter::GetAbilitySystemComponent() const
{
	return WarriorAbilitySystemComponent;
}

//当Controller(玩家或AI)获得该Pawn控制权时触发
void AWarriorBaseCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);
	if (WarriorAbilitySystemComponent)
	{
		//初始化能力系统与角色的关联关系
		WarriorAbilitySystemComponent->InitAbilityActorInfo(this, this);
	}
}


9.转到:Source/Warrior/Public/Characters/WarriorHeroCharacter.h

重写函数:PossessedBy()

protected:
	//~Begin Apawn Interface.
	virtual void PossessedBy(AController* NewController) override;	//当Controller(玩家或AI)获得该Pawn控制权时触发
	//~ End APawn Interface
	
//当Controller(玩家或AI)获得该Pawn控制权时触发
void AWarriorHeroCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);

	if (WarriorAbilitySystemComponent && WarriorAttributeSet)
	{
		// 打印信息
		const FString ASCText = FString::Printf(TEXT("Owner Actor: %s, Avator Actor: %s"), *WarriorAbilitySystemComponent->GetOwnerActor()->GetActorLabel(),*WarriorAbilitySystemComponent->GetAvatarActor()->GetActorLabel());
		Debug::Print(TEXT("ABS valid.")+ASCText, FColor::Green);
	}
}

测试了一下,可以!

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值