虚幻引擎GAS入门学习笔记(一)

虚幻引擎GAS入门(一)

  • Gameplay Ability System(GAS) 是一个模块化且强大的框架,用于管理虚幻引擎中的游戏玩法逻辑。它的核心组成部分包括 Gameplay Ability(定义和执行能力)、Gameplay Effect(应用和管理效果)、Attribute Set(管理角色属性)、Gameplay Tags(标记和管理对象状态)、Gameplay Tasks(处理异步任务)以及 Gameplay Modifiers(修改属性值)。这些组件相互协作,使得开发者能够创建复杂且高度定制化的游戏玩法,如技能系统、状态效果系统等。
  • Gameplay Ability System(GAS)组成部分及其功能
  • 学习位置UE5.3 GAS入门教程重置版 小明

创建工程

  • 创建工程然后开启GameplayAbilites插件
  • 在工程.Build.cs里添加这三个模块:"GameplayAbilities","GameplayTags","GameplayTasks"
  • 编译后会报307错误,把这几个文件删除重新构建编译一下即可
  • 创建基础角色类并新建基础角色的蓝图,然后创建两个继承这个蓝图的子类作为角色与敌人

简易角色基本控制

  • 添加一个第三人称模版,然后删除掉就会有它给你做好的轴操作控制
  • 留下需要的即可
  • 然后将导入的资产中那个蓝图里面的操作复制到我们创建的角色蓝图中去更改这个轴操作
  • 勾上

  • 勾掉这个,角色就能正常转体

2种相机模式与夹角限制

  • 首先将输入操作从角色蓝图移动到控制器蓝图中
  • 限制视角
  • 在玩家蓝图中写一个函数用来锁定相机操作

攻击动作的融合

  • 创建混合空间设置好动作行为
  • 创建动画蓝图设置初始属性



  • 配置蒙太奇
  • 攻击蒙太奇与移动进行融合,就可以边走边攻击了
  • 这个攻击蒙太奇人物会转身,为了避免这种人物突然旋转的情况,要在蒙太奇中添加通知来是否需要融合

  • 最后进行攻击动作的融合输出到最终状态

GAS结合GamePlay

  • 添加AbilitySystem组件
  • 添加技能的基类蓝图

  • 获取技能
  • 创建一个函数用来使用Melee

  • 创建一个函数用来激活技能
  • 然后在技能蓝图里面添加Melee这个标签

  • 将技能标签添加到数组中
  • 然后Melee事件调用激活技能这个函数
  • 测试一下
  • 运行结果
  • 换为播放Montage
  • 添加一个GameplayEffect技能CD,以免出现攻击反复无常的情况

  • 提交CD
  • 给剑添加碰撞盒
  • 碰撞除了自己与同类不进行碰撞处理,其他进行碰撞处理

设置角色属性

  • 新建一个AttributeSet

  • 虚幻引擎中提供了一种宏,帮助函数,可以很方便加载游戏的特殊的方法

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

  • 定义好属性
cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once

#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "BaseAttributeSet.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 GASDEMO_API UBaseAttributeSet : public UAttributeSet
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere,BlueprintReadWrite,Category = "BaseAttributeSet")
	FGameplayAttributeData HP;
	ATTRIBUTE_ACCESSORS(UBaseAttributeSet, HP);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "BaseAttributeSet")
	FGameplayAttributeData MaxHP;
	ATTRIBUTE_ACCESSORS(UBaseAttributeSet, MaxHP);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "BaseAttributeSet")
	FGameplayAttributeData MP;
	ATTRIBUTE_ACCESSORS(UBaseAttributeSet, MP);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "BaseAttributeSet")
	FGameplayAttributeData MaxMP;
	ATTRIBUTE_ACCESSORS(UBaseAttributeSet, MaxMP);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "BaseAttributeSet")
	FGameplayAttributeData Strength;
	ATTRIBUTE_ACCESSORS(UBaseAttributeSet, Strength);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "BaseAttributeSet")
	FGameplayAttributeData MaxStrength;
	ATTRIBUTE_ACCESSORS(UBaseAttributeSet, MaxStrength);
};
  • 解决小bug,武器碰撞盒子只有在挥刀的时候才开启碰撞

  • 将碰撞盒子的碰撞修改一下

伤害敌人并做夹值处理

  • 新建一个数据表把角色属性加入到里面


  • 将这个表设置到角色属性的AbilitySystem里面去
  • 再新建一个GameplayEffect作为伤害受理,每次扣血5点值

  • 在Melee攻击检测这里应用这个GE
  • 运行结果
  • 处理伤害溢出问题
  • 写上夹值逻辑
  • 运行结果

行为树配置

  • 关于两个镜头的处理,取消碰撞测试就不会让镜头被挡,启动

  • 做不同等级的伤害表,新建一个.csv的表,第一行第一列是要空着的,然后写入伤害等级值
  • 将表格拖入UE中,选择类型为曲线表格,插值类型为常量
  • 将表格插入到伤害的GE
  • 新建行为树与黑板进行配置




  • 创建AIController,然后执行行为树,将这个AIController附加到Enemy蓝图上

生命值改变时广播

  • 将所有的碰撞类型改成这样
  • 基础父类蓝图里面开始时将剑的碰撞盒子关掉
  • 把之前的动画通知改变通道变成设置碰撞
  • 在基础角色类中声明动态多播委托,因为多播委托可以在蓝图中调用
  • 创建一个多播委托的处理函数
  • 绑定多播委托

  • 订阅一下这个广播
  • 运行结果

死亡处理

  • 制作一下死亡的Montage动画
  • 添加一个死亡处理事件

停止AIController控制

  • 在敌人蓝图里面添加一个停止控制的函数
  • 在敌人蓝图里面重写一下父类中的检查血量的事件
  • 玩家蓝图中也要重写这个事件

添加敌人的血条

  • 创建一个UMG制作敌人血条

  • 在敌人蓝图中添加这个UMG组件,并写上更新UI逻辑

  • 运行结果

玩家住UI制作与构建技能结构体系

搭建玩家UI界面

  • 创建玩家的属性UI
  • 这个纹理有两个暴露出来设置的值,一个是设置百分比一个是设置颜色
  • 添加一个事件来设置血球的百分比
  • 添加一个事件来设置血球的颜色
  • 创建角色的主UI,然后设置好这三个属性球的颜色

同步UI到玩家信息

  • 在玩家控制器里面添加这个主UI窗口
  • 获取到角色的控制器,然后进行血量的数值变化逻辑

给玩家一个自动回复血量Buffer

  • 创建一个继承自基础技能的回复Buffer技能
  • 添加效果
  • 设置好技能效果的回复属性
  • 激活技能
  • 提交技能

构建技能信息结构体

  • 创建一个GameplayAbility基类
  • 创建技能信息的数据

获取技能信息与创建技能图标

获取技能详细信息函数

  • 获取技能信息
cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#include "BaseGameplayAbility.h"

FGameplayAbilityInfo::FGameplayAbilityInfo():
	CD(0),
	CostValue(0),
	CostType(ECostType::MP),
	IconMaterial(nullptr),
	AbilityClass(nullptr)
{

}

FGameplayAbilityInfo::FGameplayAbilityInfo(float CD, ECostType CostType, float CostValue, UMaterialInstance* IconMaterial, TSubclassOf<UBaseGameplayAbility> AbilityClass):
	CD(CD),
	CostType(CostType),
	CostValue(CostValue),
	IconMaterial(IconMaterial),
	AbilityClass(AbilityClass)
{

}

FGameplayAbilityInfo UBaseGameplayAbility::GetAbilityInfo(int Level)
{
	//获取与技能冷却相关的游戏效果
	UGameplayEffect* CDEffect = GetCooldownGameplayEffect();
	//获取与技能使用成本相关的游戏效果
	UGameplayEffect* CostEffect = GetCostGameplayEffect();
	float CD = 0;
	float CostValue = 0;
	ECostType CostType = ECostType::MP;
	if (CDEffect && CostEffect)
	{
		CDEffect->DurationMagnitude.GetStaticMagnitudeIfPossible(Level, CD);
		if (CostEffect->Modifiers.Num() > 0)
		{
			//获取花费的是哪一个类型
			FGameplayModifierInfo CostEffectModifierInfo = CostEffect->Modifiers[0];
			CostEffectModifierInfo.ModifierMagnitude.GetStaticMagnitudeIfPossible(Level, CostValue);
			FString CostTypeName = CostEffectModifierInfo.Attribute.AttributeName;

			if (CostTypeName == "HP")
			{
				CostType = ECostType::HP;
			}
			if (CostTypeName == "MP")
			{
				CostType = ECostType::MP;
			}
			if (CostTypeName == "Strength")
			{
				CostType = ECostType::Strength;
			}
			//返回技能信息
			return FGameplayAbilityInfo(CD, CostType, CostValue, IconMaterial, GetClass());
		}
	}
	return FGameplayAbilityInfo();
}

学习技能时就获取技能信息

  • 在基础类里面创建一个学习获取技能信息的函数
  • 学习此技能

利用结构体信息创建单个技能UI

  • 创建技能的UI
  • 设置技能Key与技能初始化
  • 设计技能开始CD逻辑
  • 更新技能图标的值,当前CD除以总CD因为材质里面的数值问题要取反,然后CD小于0的情况下就回复技能图标,并设置当前技能无CD
相关推荐
ZhaiMou2 小时前
HTML5拖拽API学习 托拽排序和可托拽课程表
前端·javascript·学习·html5
我想回家种地3 小时前
渗透学习之windows基础
学习
·云扬·3 小时前
Java IO 与 BIO、NIO、AIO 详解
java·开发语言·笔记·学习·nio·1024程序员节
小杨 学习日志5 小时前
C高级学习笔记
c语言·笔记·学习
lcintj5 小时前
【WPF】Prism学习(十)
学习·wpf·prism
NightCyberpunk6 小时前
JavaScript学习笔记
javascript·笔记·学习
努力的小陈^O^6 小时前
docker学习笔记跟常用命令总结
java·笔记·docker·云原生
李笠^_^6 小时前
Python学习------第十天
学习
红色的山茶花8 小时前
YOLOv8-ultralytics-8.2.103部分代码阅读笔记-conv.py
笔记·yolo
suzh1qian8 小时前
Unity类银河战士恶魔城学习总结(P133 Merge skill tree with Parry skill把技能树和格挡技能相组合)
学习·unity·c#·游戏引擎