UE5 GAS RPG Character Classes

ops/2025/3/6 4:34:35/

在正常的游戏中,我们应该考虑如何去初始化角色属性,并且要给角色分好类型。比如,在我们游戏中,我们如何去初始化小兵的属性,并且还要实现小兵随着等级的增长而增加属性。而且就是小兵也有类型的区分,比如我们将在后面设置小兵分为三种:战士,游侠,法师。而小兵的属性实现,一般需要策划进行配表实现,将小兵的属性统一性的存入到表格导入项目。
我们将使用枚举去定义敌人的类型并创建一个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.cppvoid AAuraEnemy::InitAbilityActorInfo()
{//初始化ActorInfoAbilitySystemComponent->InitAbilityActorInfo(this,this);//单向了解Cast<UAuraAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();//通过GE初始角色的属性InitializeDefaultAttributes();
}void AAuraEnemy::InitializeDefaultAttributes() const
{//重写覆盖父类初始化函数,但删去SuperUMyASBlueprintFunctionLibrary::InitializeDefaultAttributes(this,CharacterClass,Level,AbilitySystemComponent);
}

        调试验证

打断点处


http://www.ppmy.cn/ops/154731.html

相关文章

数据结构与算法之字符串: LeetCode 567. 字符串的排列 (Ts版)

字符串的排列 https://leetcode.cn/problems/permutation-in-string/description/ 描述 给你两个字符串 s1 和 s2 &#xff0c;写一个函数来判断 s2 是否包含 s1 的 排列。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 换句话说&#xff0c;s1 的排…

HIVE介绍(五)_hive limit

注意: 1.Hive处理的数据存储在HDFS上 2.hive分析数据的底层处理逻辑是MapReduce 3.执行运行在Yarn上执行 Hive运行原理 Hive为什么要分区&#xff08;partitioned by&#xff09;? 随着系统运行时间越来越长,表的数据量不断增大,通过hive查询通常是"全表扫描"这样就…

Linux 多路转接select

Linux 多路转接select 1. select select() 是一种较老的多路转接IO接口&#xff0c;它有一定的缺陷导致它不是实现多路转接IO的最优选择&#xff0c;但 poll() 和 epoll() 都是较新版的Linux系统提供的&#xff0c;一些小型嵌入式设备的存储很小&#xff0c;只能使用老版本的…

【Flask】在Flask应用中使用Flask-Limiter进行简单CC攻击防御

前提条件 已经有一个Flask应用。已经安装了Flask和redis服务。 步骤1&#xff1a;安装Redis和Flask-Limiter 首先&#xff0c;需要安装redis和Flask-Limiter库。推荐在生产环境中使用Redis存储限流信息。 pip install redis Flask-Limiter Flask-Limiter会通过redis存储限…

2025年01月31日Github流行趋势

项目名称&#xff1a;Qwen2.5项目地址url&#xff1a;https://github.com/QwenLM/Qwen2.5项目语言&#xff1a;Shell历史star数&#xff1a;13199今日star数&#xff1a;459项目维护者&#xff1a;jklj077, JustinLin610, bug-orz, huybery, JianxinMa项目简介&#xff1a;Qwen…

DeepSeek模型:开启人工智能的新篇章

DeepSeek模型&#xff1a;开启人工智能的新篇章 在当今快速发展的技术浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了推动社会进步和创新的核心力量之一。而DeepSeek模型&#xff0c;作为AI领域的一颗璀璨明珠&#xff0c;正以其强大的功能和灵活的用法&…

前端八股CSS:盒模型、CSS权重、+与~选择器、z-index、水平垂直居中、左侧固定,右侧自适应、三栏均分布局

一、盒模型 题目&#xff1a;简述CSS的盒模型 答&#xff1a;盒模型有两种类型&#xff0c;可以通过box-sizing设置 1.标准盒模型&#xff08;content-box&#xff09;:默认值&#xff0c;宽度和高度只包含内容区域&#xff0c;不包含内边距、边框和外边距。 2.边框盒模型&a…

C++初阶 -- 初识STL和string类详细使用接口的教程(万字大章)

目录 一、STL 1.1 什么是STL 1.2 STL的版本 1.3 STL的六大组件 二、string类 2.1 string类的基本介绍 2.2 string类的默认成员函数 2.2.1 构造函数 2.2.2 析构函数 2.2.3 赋值运算符重载 2.3 string类对象的容量操作 2.3.1 size和length 2.3.2 capacity 2.3.3 r…