[玩转UE4/UE5动画系统>技能系统(GAS)篇] 二 技能 Gameplay Ability(GA)
本教程采用圖文教程+視頻教程的多元化形式,我會為不同的知識點選擇適當的表達方式。教程內容將同步免費發布于開發游戲的老王(知乎|CSDN)的專欄《玩轉UE4/UE5動畫系統》。教程中使用的資源及工程將以開源項目的形式更新到GitHub:玩轉UE4上。
工程文件: 玩轉UE4(GitHub)
0. 效果演示
演示視頻: 技能系統 一 什么是技能系統
在本文中你將學到:
- GAS系統開發環境的配置
- 在一個Actor(Character)上配置GAS組件
- 用Effect實現兩個簡單的主動技能Jump和Attack
本教程提供的示例項目參照了官方提供的ActionRPG項目,你可以從虛幻啟動器中下載到該項目。當然也可以直接通過我提供的精簡版項目學習,我的項目中借用了虛幻官方<[中文直播]第31期|GAS插件介紹(入門篇) | 伍德 大釗>中的動畫素材。
文章目錄
- 0. 效果演示
- 1. 概要
- 2. 準備工作
- 2.1 啟動插件
- 2.2 添加編譯模塊
- 3. 實現RPGChracterBase
- 4. 案例:實現Jump技能和Attack技能
- 4.1 Jump技能
- 4.2 Attack技能
- 4.3 加載技能
- 5. 調用技能
- 5.1 聲明GameplayTag
- 5.2 為每個技能指派相應的標簽
- 5.2.1 Jump技能的標簽
- 5.2.2 Attack技能的標簽
- 5.3 在BP_PlayerCharacter中調用技能
- 6. 小結
1. 概要
下面是項目中的角色類圖,這種實現方式也參考了官方的ActionRPG項目,使用C++繼承ACharacter基類并實現IAbilitySystemInterface接口的得到ARPGCharacter,然后再派生出一個藍圖類BP_Character,接下來的玩家角色和NPC都由藍圖類派生。個人也比較推薦這種繼承模式和C++/藍圖的工作分配模式,因為除了ARPGCharacter必須由C++實現以外,其它很多工作都可以用藍圖完成,并且GAS系統中有大量的GameplayTag以及參數的配置工作,如下架構可以作為GAS開發的最佳實踐方案。
2. 準備工作
目前在UE4/5中GAS還是以插件的形式存在,所以開發之前要先進行一些必要的配置。
2.1 啟動插件
在編輯器的Plugins中開啟Gameplay Abilities插件
2.2 添加編譯模塊
在*.Build.cs文件中添加必要的編譯模塊,否則無法通過編譯
添加如下模塊
3. 實現RPGChracterBase
#pragma once#include "CoreMinimal.h" #include "GameFramework/Character.h" #include "AbilitySystemInterface.h" #include "RPGCharacterBase.generated.h"UCLASS() class ARPGCharacterBase : public ACharacter,public IAbilitySystemInterface {GENERATED_BODY()public:ARPGCharacterBase();virtual void BeginPlay() override; protected:UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "Character Abilities")class UAbilitySystemComponent* AbilitySystemComponent;UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = "Character Abilities")TArray<TSubclassOf<class UGameplayAbility>> PreloadedAbilities; public:virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;};如我們所見,實現最基礎的GAS系統非常簡單,只要實現IAbilitySystemInterface接口就可以了。IAbilitySystemInterface接口,而這個接口最重要的作用就是實現一個GetAbilitySystemComponent方法。如我在本系列第一篇文章《什么是技能系統》所說,AbilitySystemComponent是技能的容器、管理器以及各個GAS角色之間對話的橋梁。
上面代碼中還添加了一個PreloadedAbilities字段,它是一個數組,我們可以預先為角色添加一些預加載技能。使得角色誕生時就會擁有一些技能,但是它并不是必須的。因為GAS允許我們在游戲運行時隨時隨地為角色動態地加載或卸載技能。
#include "RPG/Public/RPGCharacterBase.h" #include "AbilitySystemComponent.h"ARPGCharacterBase::ARPGCharacterBase() {PrimaryActorTick.bCanEverTick = true;AbilitySystemComponent = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystem")); }UAbilitySystemComponent* ARPGCharacterBase::GetAbilitySystemComponent() const {return AbilitySystemComponent; }// Called when the game starts or when spawned void ARPGCharacterBase::BeginPlay() {Super::BeginPlay();if(AbilitySystemComponent != nullptr){if(PreloadedAbilities.Num() > 0){for(auto i =0;i < PreloadedAbilities.Num(); i++){if(PreloadedAbilities[i] != nullptr){AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(PreloadedAbilities[i].GetDefaultObject(),1,0));}}}AbilitySystemComponent->InitAbilityActorInfo(this,this);} }請注意上面代碼中的AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(PreloadedAbilities[i].GetDefaultObject(),1,0));部分,把技能放在PreloadedAbilities中并不代表角色擁有技能,GiveAbility(授予技能)才是讓角色的AbilitySystemComponent獲得(或學習到)技能。
有朋友可能會問,這樣一股腦地把技能加載到AbilitySystemComponent中,我們以后該如何調用它們呢?方法其實超級簡單,不過先賣個關子,一會兒介紹。
上述代碼編譯過后,角色就擁有了GAS組件以及預加載技能的數組。
4. 案例:實現Jump技能和Attack技能
在UGameplayAbility中可以獲取到Actor以及其各個組件的引用,因此小到跳躍達到必殺技等等都可以用技能實現。所以除了基本移動這種通用邏輯不推薦使用技能實現,其它所有技能都可以放到技能中,這樣既能夠讓邏輯解耦合又可以方便我們自由裝卸。本文中的Jump和Attack技能僅為示例,幫助初學者了解GAS的工作原理。
4.1 Jump技能
技能(Ability)的實現可以使用C++也可以使用藍圖,本例中的兩個技能都是使用藍圖實現的。
新建一個派生自GameplayAbility的藍圖類,并命名為GA_Jump(技能藍圖一般以GA_開頭)
Jump的邏輯非常簡單
實際上在技能系統的插件中開發者已經幫我們用C++實現了一個Jump技能。
- ActivateAbility即當技能被激活時觸發的事件,OnEndAbility是結束技能時觸發的事件。
- 在UGameplayAbility中通過GetActorInfo可以獲取到所屬角色的信息
- 一個技能一旦被激活,如果不在技能內部調用EndAbility或者在外部終止技能,技能是不會自動終止并一直保持在激活狀態,這點一定要注意。
4.2 Attack技能
新建一個派生自GameplayAbility的藍圖類,并命名為GA_Attack。
Attack技能的邏輯也非常簡單,僅僅是播放一個角色揮拳動畫的蒙太奇,結束以后終止技能。
別忘了在動畫藍圖中添加蒙太奇的Slot
4.3 加載技能
實現完技能以后別忘了把它們放到BP_PlayerCharacter的PreloadedAbilities,這樣當程序啟動,他們就會自動加載到AbilitySystemComponent里面。
5. 調用技能
如何調用技能?是時候揭曉謎底了,可以使用GameplayTag!
當然,調用技能還有很多其它方法,老王覺得用GameplayTag召喚技能是最靈活的一種方式,那么其它方法就留給大家自己解鎖吧。
5.1 聲明GameplayTag
在Project Settings中添加或編輯GameplayTag,需要注意的是當未來技能很多很復雜的時候標簽系統也會變得復雜,因此如何為自己的游戲定義標簽系統是一個值得好好規劃的問題。
本例中我在Ability父級標簽下定義了兩個子標簽分別對應著Jump和Attack技能。
5.2 為每個技能指派相應的標簽
在GAS中GameplayTag定義著技能之間相生相克的關系,每個標簽的具體含義大家可以參考這里《GASDocumentation》中的Ability Tags
5.2.1 Jump技能的標簽
- Ability Tags: 召喚或取消這個技能所需的標簽,可以理解為這個技能的名字或種類名。
- Block Abilities with Tag:是指當這個技能被激活時,擁有該標簽的其它標簽將不能被激活,我把它設為Ability.Jump是為了防止當一個跳躍技能未完成前再次觸發一個跳躍技能。
5.2.2 Attack技能的標簽
Attack技能的標簽和Jump邏輯基本相同。
主要是這個例子很簡單,當技能多了,相生相克關系也會隨之復雜。
5.3 在BP_PlayerCharacter中調用技能
在BP_PlayerCharacter中直接用GameplayTag就可以召喚出相應的技能,是不是超級簡單?
為什么Activate Ability 前面要加個Try呢?因為我們召喚技能以后技能到底能不能被激活還要受到和它相生相克的其它因素(標簽)所制約,所以我們只能Try一下。
6. 小結
經過上述幾個簡單的步驟,我們就用GAS實現兩個小技能。是不是很簡單?但是這個示例還遠遠沒有體現出GAS的威力,而且Jump和Attack都是我們主動召喚的,下一篇文章我們將了解如何輕松實現一個被動技能,并且學會使用Effect進行GAS角色之間的對話。
總結
以上是生活随笔為你收集整理的[玩转UE4/UE5动画系统>技能系统(GAS)篇] 二 技能 Gameplay Ability(GA)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JMM理论二:相关概念——重排序、内存屏
- 下一篇: Kinect for Windows S