UE5 GAS RPG Character Classes

news/2025/2/1 8:53:04 标签: ue5, c++

在正常的游戏中,我们应该考虑如何去初始化角色属性,并且要给角色分好类型。比如,在我们游戏中,我们如何去初始化小兵的属性,并且还要实现小兵随着等级的增长而增加属性。而且就是小兵也有类型的区分,比如我们将在后面设置小兵分为三种:战士,游侠,法师。而小兵的属性实现,一般需要策划进行配表实现,将小兵的属性统一性的存入到表格导入项目。
我们将使用枚举去定义敌人的类型并创建一个ECharacterClass,并创建一个DataAsset命名为UCharacterClassInfo用来设置每种类型使用的属性初始化的GE。对于随着等级变动的基础属性,我们将使用曲线表格去生成所有等级的数据。并且,在数据中,我们去设置敌人需要附带的技能。
所以,接下来,我们实现的步骤是:

  1. 创建DataAsset储存UCharacterClassInfo
// YanWei.

#pragma once

#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "CharacterClassInfo.generated.h"

class UGameplayEffect;
//角色职业类型的枚举
UENUM(BlueprintType)
enum class ECharacterClass : uint8
{
	Elementalist, //法师
	Warrior, //战士
	Ranger //游侠
};

USTRUCT()
struct FCharacterClassDefaultInfo
{
	GENERATED_BODY()
	
	UPROPERTY(EditDefaultsOnly, Category="Class Defaults")
	TSubclassOf<UGameplayEffect> PrimaryAttributes;
	
};

/**
 * 根据职业选择初始化角色的数据
 */
UCLASS()
class AURA_API UCharacterClassInfo : public UDataAsset
{
	GENERATED_BODY()
	
public:
	//用于根据不同的职业选择不同的结构体,
	UPROPERTY(EditDefaultsOnly, Category="Class Defaults")
	TMap<ECharacterClass, FCharacterClassDefaultInfo> CharacterClassInformation;
	
	UPROPERTY(EditDefaultsOnly, Category="Common Class Defaults")
	TSubclassOf<UGameplayEffect> SecondaryAttributes;
	
	UPROPERTY(EditDefaultsOnly, Category="Common Class Defaults")
	TSubclassOf<UGameplayEffect> VitalAttributes;

	//通过枚举获取对应的初始化类
	FCharacterClassDefaultInfo GetClassDefaultInfo(ECharacterClass CharacterClass);
};


// YanWei.


#include "AbilitySystem/Data/CharacterClassInfo.h"

FCharacterClassDefaultInfo UCharacterClassInfo::GetClassDefaultInfo(ECharacterClass CharacterClass)
{
	return CharacterClassInformation.FindChecked(CharacterClass);
}

        2. 创建GE去填充DA_CharacterInfo

         3.创建GE使用的 CurveTable 

依次是  常数  线性  立方体(平滑曲线)

                操作流程   添加n个关键帧->三次插值自动切线

        4.CurveTable 填入GE

还有另外两种方法  CSV 和 JSON

  •         现在通过设置好的通用GE去实例化Enemy

        创建完成对应的GE,我们并使用数据表格填充了对应的数据,接下来,我们将通过代码实现对应的逻辑去初始化角色。
        首先,我们考虑将创建数据放在哪里,这里我们将其放到GameMode上面,对于GameMode来说,在不同场景可以设置不同的GameMode,刚好合适,比如你创建了一个关卡,可以设置上对应的数据,关卡内的敌人初始化时,就使用这一套GE去初始化。
在我们的GameMode基类上增加一个变量,用于设置数据   蓝图中设置CharacterClassInofo(DataAsset)

        在函数库增加一个函数,用于初始角色属性

//函数的实现
void UMyASBlueprintFunctionLibrary::InitializeDefaultAttributes(const UObject* WorldContextObject,
	ECharacterClass CharacterClass, float Level, UAbilitySystemComponent* ASC)
{
	//这里需要用到ASC去索引到AvatarActor 才能应用GE属性 
	AActor* AvatarActor = ASC->GetAvatarActor();
	
	//获取到当前关卡的GameMode实例
	const AAuraGameModeBase* GameMode = Cast<AAuraGameModeBase>(UGameplayStatics::GetGameMode(WorldContextObject));
	if(GameMode == nullptr) return;

	//从实例获取到关卡角色的配置
	UCharacterClassInfo* ClassInfo = GameMode->CharacterClassInfo;

	//获取到默认的基础角色数据
	const FCharacterClassDefaultInfo ClassDefaultInfo = ClassInfo->GetClassDefaultInfo(CharacterClass);

	//应用基础属性
	FGameplayEffectContextHandle PrimaryContextHandle = ASC->MakeEffectContext();
	PrimaryContextHandle.AddSourceObject(AvatarActor);
	const FGameplayEffectSpecHandle PrimarySpecHandle = ASC->MakeOutgoingSpec(ClassDefaultInfo.PrimaryAttributes, Level, PrimaryContextHandle);
	ASC->ApplyGameplayEffectSpecToSelf(*PrimarySpecHandle.Data.Get());

	//设置次级属性
	FGameplayEffectContextHandle SecondaryContextHandle = ASC->MakeEffectContext();
	SecondaryContextHandle.AddSourceObject(AvatarActor);
	const FGameplayEffectSpecHandle SecondarySpecHandle = ASC->MakeOutgoingSpec(ClassInfo->SecondaryAttributes, Level, SecondaryContextHandle);
	ASC->ApplyGameplayEffectSpecToSelf(*SecondarySpecHandle.Data.Get());

	//填充血量和蓝量
	FGameplayEffectContextHandle VitalContextHandle = ASC->MakeEffectContext();
	VitalContextHandle.AddSourceObject(AvatarActor);
	const FGameplayEffectSpecHandle VitalSpecHandle = ASC->MakeOutgoingSpec(ClassInfo->VitalAttributes, Level, VitalContextHandle);
	ASC->ApplyGameplayEffectSpecToSelf(*VitalSpecHandle.Data.Get());
	
}

        然后需要在Enemy.h中设置 职业变量并 InitInfo使用上面实现的函数nitializeDefaultAttributes()

	//TODO:: 用于给不同敌人划分不同职业
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Character Class Defaults" )
	ECharacterClass CharacterClass = ECharacterClass::Warrior;
    //重写父类初始化函数
    virtual void InitializeDefaultAttributes() const override;

//--Enemt.cpp

void AAuraEnemy::InitAbilityActorInfo()
{
	//初始化ActorInfo
	AbilitySystemComponent->InitAbilityActorInfo(this,this);
	//单向了解
	Cast<UAuraAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();
	//通过GE初始角色的属性
	InitializeDefaultAttributes();
}

void AAuraEnemy::InitializeDefaultAttributes() const
{
	//重写覆盖父类初始化函数,但删去Super
	UMyASBlueprintFunctionLibrary::InitializeDefaultAttributes(this,CharacterClass,Level,AbilitySystemComponent);
}

        调试验证

打断点处


http://www.niftyadmin.cn/n/5839221.html

相关文章

新月智能护甲系统CMIA--未来战场的守护者

新月智能护甲系统&#xff08;Crescent Moon Intelligent Armor System&#xff0c;简称CMIA&#xff09; 新月智能护甲系统&#xff08;CMIA&#xff09;是新月结合了她多年的研究成果&#xff0c;开发出的一款高度智能化的个人防护装备。这款护甲集成了先进的环境监测、生命…

玩转大语言模型——配置图数据库Neo4j(含apoc插件)并导入GraphRAG生成的知识图谱

系列文章目录 玩转大语言模型——使用langchain和Ollama本地部署大语言模型 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 玩转大语言模型——使用GraphRAGOllama构建知识图谱 玩转大语言模型——完美解决Gra…

VUE之组件通信(一)

1、props 概述&#xff1a;props是使用频率最高的一种通信方式&#xff0c;常用与&#xff1a;父<——>子。 若 父传子&#xff1a;属性值是非函数。若 子传父&#xff1a;属性值是函数。 父组件&#xff1a; <template><div class"father">&l…

Python NumPy(7):连接数组、分割数组、数组元素的添加与删除

1 连接数组 函数描述concatenate连接沿现有轴的数组序列stack沿着新的轴加入一系列数组。hstack水平堆叠序列中的数组&#xff08;列方向&#xff09;vstack竖直堆叠序列中的数组&#xff08;行方向&#xff09; 1.1 numpy.concatenate numpy.concatenate 函数用于沿指定轴连…

解决makailio的 kamctl命令的错误

创建FIFO文件并设置权限&#xff1a; 如果FIFO文件不存在&#xff0c;可以手动创建它并设置正确的权限。 mkdir -p /run/kamailio mkfifo /run/kamailio/kamailio_rpc.fifo# 如果设置了权限 要继续执行 chown kamailio:kamailio /run/kamailio/kamailio_rpc.fifo chmod 660 /r…

[Collection与数据结构] B树与B+树

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

第05章 18 vtkCutter切割类及与之相似的类说明

vtkCutter 是 VTK&#xff08;Visualization Toolkit&#xff09;中的一个类&#xff0c;用于通过几何体&#xff08;如多边形网格、曲面等&#xff09;进行切割操作&#xff0c;生成切割后的等值面或多段线。它通常用于生成等值线图、等值面或其他类型的切割效果。 vtkCutter…

Keepalived高可用集群入门学习

一、高可用集群 1.LB&#xff1a;load Balance 负载均衡 HA&#xff1a;High Availability 高可用集群 HPC: High Performance Computing 高性能集群 2.提高系统高用性的解决方案&#xff1a;降低MTTR&#xff08;mean time to repair&#xff09;平均故障时间 建立冗余机制…