跳到主要内容
信息
文章中可能会出现一些错误,希望大佬们可以在评论区指出错误,感谢支持!

02 - Ability System Component

本文主要说明了UE5中Gameplay技能系统(Gameplay Ability System, GAS)中有关 Ability System Component(ASC)的相关内容。

概述

技能系统组件(UAbilitySystemComponent,简称ASC)是Actor和GAS之间的桥梁。Actor需要拥有自己的技能系统组件,或访问PlayerState或Pawn上的技能系统组件,才能与GAS进行互动。

要让Actor参与到GAS中,需要让它重写实现IAbilitySystemInterface接口中的GetAbilitySystemComponent()函数。这是因为在部分情况下会使用其他Actor的ASC,如果不实现该函数就会让获取流程变复杂。

基础知识

Owner Actor和Avatar Actor

ASC的所有者有Owner Actor和Avatar Actor之分:

  • Owner Actor:是ASC的逻辑所有者,也就是实际拥有该ASC的Actor;
  • Avatar Actor:是ASC的物理表现载体,也就是实际执行Gameplay Ability等特性的Actor;

这两个Actor将ASC的所有权和表现层进行分离,方便开发者进行相关开发。

通过执行InitAbilityActorInfo()函数以初始化这两个Actor,一般来说,执行该函数的时机如下:

  • 对于玩家控制的角色,在设置好Controller的所有权后:
    • ASC的Owner Actor是Pawn:服务端在PossessedBy()中执行;客户端在AcknowledgePossession()中执行;
    • ASC的Owner Actor是PlayerState:服务端在PossessedBy()中执行;客户端在OnRep_PlayerState()中执行;
  • 对于AI控制的角色,如果ASC的Owner Actor是Pawn,则在BeginPlay()中执行即可;

例如在Aura项目中,玩家的ASC在AAuraPlayerState类中被初始化,在AAuraCharacter::InitAbilitySystem()中通过IAbilitySystemInterface接口中的GetAbilitySystemComponent()函数被获取,并设置这两个Actor:

AuraCharacter.cpp点击展开/折叠代码
void AAuraCharacter::InitAbilitySystem()
{
AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
checkf(AuraPlayerState, TEXT("Can't get AuraPlayerState !!!"));
AuraPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(AuraPlayerState, this);

// ...
}

网络同步

要想启用ASC的网络同步,需要在初始化ASC时执行SetIsReplicated(true)

Replication Mode

执行SetIsReplicated(true)后,还需要执行SetReplicationMode()以设置ASC的网络同步模式。ASC的网络同步模式主要有如下三种:

  1. Full:适用于极少数玩家场景(单机/局域网), Gameplay Effects会被同步到所有客户端中;
  2. Mixed:适用于多人游戏, 玩家控制的Actor, Gameplay Effects只会被同步到玩家拥有的客户端中,Gameplay Cues 和 Gameplay Tags 会被同步到所有客户端中;
  3. Minimal:适用于多人游戏, AI控制的Actor, Gameplay Effects不会被同步, Gameplay Cues 和 Gameplay Tags 会被同步到所有客户端中;

此外,对于Mixed模式,它的OwnerActor必须是Controller。

常用操作

以下内容是关于ASC的常用操作,笔者会根据自己使用情况进行更新。

GE相关

绑定GE施加时的回调函数

ASC通过定义若干委托以允许我们绑定GE施加时的回调函数:

AbilitySystemComponent.h点击展开/折叠代码
/** Delegate for when an effect is applied */
DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnGameplayEffectAppliedDelegate, UAbilitySystemComponent*, const FGameplayEffectSpec&, FActiveGameplayEffectHandle);

/** Called on server whenever a GE is applied to self. This includes instant and duration based GEs. */
FOnGameplayEffectAppliedDelegate OnGameplayEffectAppliedDelegateToSelf;

/** Called on server whenever a GE is applied to someone else. This includes instant and duration based GEs. */
FOnGameplayEffectAppliedDelegate OnGameplayEffectAppliedDelegateToTarget;

/** Called on both client and server whenever a duration based GE is added (E.g., instant GEs do not trigger this). */
FOnGameplayEffectAppliedDelegate OnActiveGameplayEffectAddedDelegateToSelf;

/** Called on server whenever a periodic GE executes on self */
FOnGameplayEffectAppliedDelegate OnPeriodicGameplayEffectExecuteDelegateOnSelf;

/** Called on server whenever a periodic GE executes on target */
FOnGameplayEffectAppliedDelegate OnPeriodicGameplayEffectExecuteDelegateOnTarget;

我们需要根据情况和GE的类型选择对应的委托,然后创建相关回调函数并绑定。

参考资料