🎮 GAS系统在多人游戏中的设置差异与初始化时机
一、概述
**多人游戏(Networked Game)**中,由于存在服务器与多个客户端的结构,GAS 的使用必须区分不同对象在运行时的职责和行为。
二、GAS核心对象与角色差异
对象名称 |
功能说明 |
Owner Actor |
GAS组件的拥有者(通常为PlayerState,便于跨控制器持久化)。 |
Avatar Actor |
能力的执行者(通常为Character或Pawn)。 |
Controller |
控制角色的输入源(客户端中为PlayerController)。 |
Server(Authority) |
权威角色,处理所有真实逻辑、能力应用、属性变化。 |
Client |
接收结果并本地预测显示,仅可请求、不能决定游戏状态。 |
三、各端差异汇总
1. 能力激活与同步
操作内容 |
服务器 |
本地客户端 |
远程客户端 |
激活Ability |
权威执行 |
预测激活 |
不能激活 |
应用GameplayEffect |
执行并广播 |
预测申请 |
被动接收 |
属性变化(如HP) |
计算更新 |
仅接受同步 |
被动同步 |
动画等表现 |
播放实际动画 |
播放预测动画 |
接收并展示 |
四、初始化流程详解
1. 关键函数
InitAbilityActorInfo(OwnerActor, AvatarActor)
初始化 GAS,使其知道“谁拥有”与“谁在表现能力”。
GiveAbility
/ ApplyGameplayEffectToSelf
授予技能与初始属性,仅应由服务器执行。
BindAbilityActivationToInputComponent
客户端绑定输入与Ability激活。
2. 初始化顺序与执行位置
步骤 |
函数 |
执行端 |
说明 |
1 |
构造 / BeginPlay |
所有 |
创建AbilitySystemComponent指针 |
2 |
PossessedBy |
服务器 |
初始化 GAS + 授予能力和属性 |
3 |
OnRep_PlayerState |
客户端 |
重新初始化 GAS 以同步服务器信息 |
4 |
SetupPlayerInputComponent |
本地客户端 |
绑定输入到Ability |
3. 推荐实现结构(Character类)
// 服务器端:控制器接管后初始化 GAS
void AMyCharacter::PossessedBy(AController* NewController)
{
Super::PossessedBy(NewController);
AbilitySystemComponent->InitAbilityActorInfo(GetPlayerState(), this);
GrantDefaultAbilities(); // 授予能力和属性
}
// 客户端:同步PlayerState后初始化 GAS
void AMyCharacter::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
AbilitySystemComponent->InitAbilityActorInfo(GetPlayerState(), this);
}
// 输入绑定(本地控制客户端)
void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
if (IsLocallyControlled())
{
AbilitySystemComponent->BindAbilityActivationToInputComponent(
InputComponent,
FGameplayAbilityInputBinds("Confirm", "Cancel", "EAbilityInputID")
);
}
}