7. UE5 RPG修改GAS的Attribute的值

前面几节文章介绍了如何在角色身上添加AbilitySystemComponent和AttributeSet。并且还实现了给AttributeSet添加自定义属性。接下来,实现一下如何去修改角色身上的Attribute的值。

实现拾取药瓶回血功能

首先创建一个继承于Actor的c++类,actor是可以放置到场景中的基类。

bash 复制代码
	UPROPERTY(VisibleAnywhere)
	TObjectPtr<UStaticMeshComponent> Mesh;

创建一个静态模型组件,用来显示当前可拾取物的模型。

bash 复制代码
	UPROPERTY(VisibleAnywhere)
	TObjectPtr<USphereComponent> Sphere;

创建一个碰撞体球,用于检测和主角的碰撞来触发回调。

bash 复制代码
	Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
	SetRootComponent(Mesh);

	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
	Sphere->SetupAttachment(GetRootComponent());

然后初始化中,创建对象,并将Mesh设置为根节点,并将球碰撞体挂在Mesh下面。

bash 复制代码
UFUNCTION()
virtual void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

UFUNCTION()
virtual void EndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

创建两个回调,用于碰撞触发的开始和结束。

bash 复制代码
	Sphere->OnComponentBeginOverlap.AddDynamic(this, &AEffectActorBase::OnOverlap);
	Sphere->OnComponentEndOverlap.AddDynamic(this, &AEffectActorBase::EndOverlap);

绑定到球体碰撞事件上,如果球体触发了碰撞,则会调用这两个函数。

bash 复制代码
void AEffectActorBase::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	//TODO: 为了测试数值修改功能,启用了常量转变量功能。
	if(IAbilitySystemInterface* ASCInterface = Cast<IAbilitySystemInterface>(OtherActor))
	{
		 //根据类从ASC里面获取到对应的AS实例
		const UAttributeSetBase* AttributeSet = Cast<UAttributeSetBase>(ASCInterface->GetAbilitySystemComponent()->GetAttributeSet(UAttributeSetBase::StaticClass()));
		UAttributeSetBase* MutableAttributeSet = const_cast<UAttributeSetBase*>(AttributeSet); //将常量转为变量
		MutableAttributeSet->SetHealth(AttributeSet->GetHealth() + 25.f);
		Destroy(); // 销毁自身
	}
}

接着在碰撞触发的时候,从接口获取到AttributeSet,然后设置数值增长。

接下来在UE里面创建一个蓝图,基于EffectActorBase。

左侧会发现我们在代码中添加的Mesh和Sphere。

添加模型网格体,然后调整球的大小。

运行场景,输入showdebug abilitysystem

如果值修改,那证明功能实现。

EffectActorBase.h

bash 复制代码
// 版权归暮志未晚所有。

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EffectActorBase.generated.h"

class USphereComponent;
class UStaticMeshComponent;

UCLASS()
class AURA_API AEffectActorBase : public AActor
{
	GENERATED_BODY()
	
public:	
	AEffectActorBase();

	UFUNCTION()
	virtual void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

	UFUNCTION()
	virtual void EndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
	
protected:
	// 游戏开始或生成对象时回调
	virtual void BeginPlay() override;

private:
	UPROPERTY(VisibleAnywhere)
	TObjectPtr<USphereComponent> Sphere;

	UPROPERTY(VisibleAnywhere)
	TObjectPtr<UStaticMeshComponent> Mesh;
};

EffectActorBase.app

bash 复制代码
// 版权归暮志未晚所有。


#include "Actor/EffectActorBase.h"

#include "AbilitySystemComponent.h"
#include "AbilitySystemInterface.h"
#include "AbilitySystem/AttributeSetBase.h"
#include "Components/SphereComponent.h"

AEffectActorBase::AEffectActorBase()
{
 	// 设置当前对象是否每帧调用Tick()
	PrimaryActorTick.bCanEverTick = false;

	Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
	SetRootComponent(Mesh);

	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
	Sphere->SetupAttachment(GetRootComponent());
}

void AEffectActorBase::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	//TODO: 为了测试数值修改功能,启用了常量转变量功能。
	if(IAbilitySystemInterface* ASCInterface = Cast<IAbilitySystemInterface>(OtherActor))
	{
		 //根据类从ASC里面获取到对应的AS实例
		const UAttributeSetBase* AttributeSet = Cast<UAttributeSetBase>(ASCInterface->GetAbilitySystemComponent()->GetAttributeSet(UAttributeSetBase::StaticClass()));
		UAttributeSetBase* MutableAttributeSet = const_cast<UAttributeSetBase*>(AttributeSet); //将常量转为变量
		MutableAttributeSet->SetHealth(AttributeSet->GetHealth() + 25.f);
		Destroy(); // 销毁自身
	}
}

void AEffectActorBase::EndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
}

void AEffectActorBase::BeginPlay()
{
	Super::BeginPlay();

	Sphere->OnComponentBeginOverlap.AddDynamic(this, &AEffectActorBase::OnOverlap);
	Sphere->OnComponentEndOverlap.AddDynamic(this, &AEffectActorBase::EndOverlap);
}
相关推荐
风酥糖6 小时前
Godot游戏练习01-第24节-多人游戏暂停菜单,游戏优化
游戏·游戏引擎·godot
CDN3606 小时前
游戏盾 SDK 混淆后失效?豁免规则与打包配置解决方案
运维·游戏·网络安全
huwuhang7 小时前
Winkawaks街机游戏模拟器整合ROM版 1.65 汉化修正完整版 2026.03.30
android·游戏·游戏机
智算菩萨8 小时前
【Pygame】第20章 从0到1构建贪吃蛇:基于Pygame的游戏架构与状态机设计实战(有超详细中文注释)
python·游戏·pygame
wanhengidc10 小时前
云手机 性能不受限 数据安全
服务器·网络·安全·游戏·智能手机
ZJH__GO11 小时前
java--飞机大战游戏
java·游戏
智算菩萨11 小时前
【Pygame】第23章 平台跳跃游戏:基于有限状态机的2D平台物理模拟与摄像机视口管理系统(有超详细中文注释供大家学习)
python·游戏·pygame
CCIE-Yasuo11 小时前
《永恒战士2-无双战神》无限金币版(提供apk下载)安卓Android逆向记录学习-Deepseek-AI辅助
android·java·学习·游戏
代码小书生12 小时前
Windows X-Lite Win11 26H1 v3 游戏优化系统!集Win11、Win10、Win7三代优点,兼顾游戏办公生产算力,系统精简纯净
windows·游戏·windows x-lite·windows 游戏版·windows优化版·老电脑系统
竹之却12 小时前
【Minecraft】无法连接至服务器,登录失败:无效会话(请尝试重启游戏及启动器)
运维·服务器·游戏·我的世界·minecraft