InitAbilityActorInfo 在 Player 与 AI 上的区别

GAS 核心:InitAbilityActorInfo 在 Player 与 AI 上的区别

在虚幻引擎的 GAS (Gameplay Ability System) 中,InitAbilityActorInfo 是一个核心函数,用于建立技能系统组件 (ASC) 与角色之间的"所有权"关系。理解它在玩家角色和 AI 角色之间的区别,是正确实现网络同步和角色重生的关键。

核心概念:Owner 与 Avatar

在调用 InitAbilityActorInfo 时,需要传入两个重要参数:

  • OwnerActor (拥有者):负责网络复制和持久存储(属性、技能CD、经验值等)。通常是整个生命周期中相对稳定的对象。
  • AvatarActor (代言人):负责视觉表现和输入接收(移动、动画、蒙太奇等)。通常是世界中实际被玩家看到和控制的那个物体。

简单的理解:Owner 是"档案",Avatar 是"化身"。档案需要持久保存,化身可以根据需要更换。


1. 针对玩家控制的角色 (Player Character)

玩家角色需要支持重生网络同步本地输入等复杂逻辑。

调用时机

通常在 PossessedBy 函数中调用(仅服务器执行)。

参数设置

  • OwnerActorPlayerState
  • AvatarActorCharacter 自身

2. 针对 AI 控制的角色 (AI Character)

通常在构造函数或 BeginPlay 中调用(不需要 PossessedBy 逻辑)。

  • 拥有者与代言人通常是合一的

    • OwnerActorAI Character 自身

    • AvatarActorAI Character 自身

  • 原因:AI 通常没有像 PlayerState 那样需要跨重生保留的中间层,且 AI 不参与玩家那样的复杂客户端预测,直接将 ASC 放在身上最简单。

  • 网络环境:如果开启了 Dedicated Server,AI 通常存在于 Server 端。


💡 为什么要这样做? (关键点)

  1. 玩家重生的秘密
    如果玩家角色死亡并被销毁,但 ASC 放在 PlayerState 里,PlayerState 不会销毁。当新角色被 Possessed 时,只需重新调用 InitAbilityActorInfo,将新角色设置为 AvatarActor,就能无缝继承之前的所有技能和状态。

  2. AI 的简单逻辑
    AI 通常是一命通关(死了就没了),或者很简单地重生为一个新物体。不需要保留旧的状态,所以把 ASC 放在身上更省事。

  3. 网络性能
    玩家的 PlayerState 在所有客户端都存在,用它作为 OwnerActor 能保证属性(如血量)在所有机器上都能被正确同步和访问。AI 如果在客户端只是模拟移动,通常不需要同步复杂的 GAS 属性给所有客户端(除非必要)。


代码详情

对于玩家:

void AAuraCharacter::PossessedBy(AController* NewController) {
	Super::PossessedBy(NewController);
	//init ability actor info for server

	InitAbilityActorInfo();

}

void AAuraCharacter::OnRep_PlayerState()
{
	Super::OnRep_PlayerState();

	//init ability actor info for client

	InitAbilityActorInfo();

}

void AAuraCharacter::InitAbilityActorInfo()
{
	AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
	check(AuraPlayerState);

	AuraPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(AuraPlayerState, this);

	AbilitySystemComponent = AuraPlayerState->GetAbilitySystemComponent();
	AttributeSet = AuraPlayerState->GetAttributeSet();
}

对于AI:

void AAuraEnemy::BeginPlay() {
	
	Super::BeginPlay();

	AbilitySystemComponent->InitAbilityActorInfo(this, this);
}
posted @ 2026-06-15 13:44  Yokino123  阅读(25)  评论(0)    收藏  举报