https://dev.epicgames.com/documentation/ko-kr/unreal-engine/gameplay-ability-system-component-and-gameplay-attributes-in-unreal-engine?application_version=5.3

 

언리얼 엔진의 게임플레이 어빌리티 시스템 컴포넌트 및 게임플레이 어트리뷰트를 살펴봅니다.

게임플레이 어트리뷰트 및 어트리뷰트 세트와 함께 어빌리티 시스템 컴포넌트를 사용하는 방법을 살펴봅니다.

dev.epicgames.com

  • UGameAbilitySystemComponent는 Actor와 GAS 사이의 가교 역할을 한다.
  • GAS와 상호작용해야 하는 Actor는 다음 2가지 조건 중 하나를 반드시 만족해야 한다.
    • Ability System Component(이하 ASC)를 가지고 있거나
    • 다른 Actor의 ASC에 Access 할 수 있거나.
  • ASC는 FGameplayAbilitySpecContainer ActivatableAbilities 중 승인된 Gameplay Abilities를 가지고 있다.
  • 언제나 ActivatableAbilities.Items를 통해 iterate를 하려 한다면,
    List의 변화를 막기 위해 ABILITY_SCOPE_LOCK()을 반복문 앞에 추가해 Lock을 걸어야 한다.
  • 매 ABILITY_SCOPE_LOCK() 호출 범위마다 AbilityScopeLockCount가 증가하고,
    그 범위를 벗어나면 AbilityScopeLockCount가 감소한다.
  • ABILITY_SCOPE_LOCK() 호출 범위 내에서 Ability를 제거하지 말 것.
    • List가 Lock이 걸려 있으면 AbilityScopeLockCount를 확인하여 제거를 방지한다.

기본 요구사항

  • Actor가 Game Ability System를 사용하려면 다음 2가지를 충족해야 한다.
    • IAbilitySystemInterface 구현
    • GetAbilitySystemComponent 함수 override
  • Actor가 자체 ASC를 가지고 있는 것이 일반적이다.
  • 하지만 다른 Actor가 소유한 ASC를 사용하려는 경우가 있다.
    • Player의 Pawn/Character가 소환/소멸 되거나 처리할 때 리셋되면 안되는 것들이 포함되어 있기 때문.

Replication Mode

  • ASC는 GameplayEffects, GameplayTags, GameplayCues에 대해 3가지 Replication Mode를 제공한다.
  • Attributes는 속한 AttributeSet에 의해 Replicate된다.

Full

  • Single Player에서 사용
  • 모든 GameplayEffects가 모든 Client에 Replicate된다.

Mixed

  • Multiplayer에서 유저가 Control 하는 Actor
  • GameplayEffects가 소유한 Client에게만 Replicate된다.
  • GameplayTags와 GameplayCues만 모두에게 Replicate된다.

Advanced

  • 이 Mode에서 OwnerActor의 Owner가 Controller가 되는 것을 권장한다.
    • PlayerState의 Parent는 기본적으로 Controller이지만, Character는 그렇지 않다.
    • OwnerActor가 PlayerState가 아닌 상태에서 Mixed Mode를 사용하는 경우, 
      SetOwner() 함수를 호출해 OwnerActor를 Controller로 명시해야 한다.
    • 4.24 버전 이후(현재)에는 PossessedBy() 함수로 Owner를 Controller로 지정한다.

Minimal

  • Multiplayer에서 AI가 Control 하는 Actor
  • GameplayEffects가 어디에도 Replicate 되지 않는다.
  • GameplayTags와 GameplayCues만 모두에게 Replicate 된다.

예시

 

GitHub - tranek/GASDocumentation: My understanding of Unreal Engine 5's GameplayAbilitySystem plugin with a simple multiplayer s

My understanding of Unreal Engine 5's GameplayAbilitySystem plugin with a simple multiplayer sample project. - tranek/GASDocumentation

github.com

ASC가 Actor에 있는 경우

  • 더보기
    AGDPlayerState::AGDPlayerState()
    {
    	// Create ability system component, and set it to be explicitly replicated
    	AbilitySystemComponent = CreateDefaultSubobject<UGDAbilitySystemComponent>(TEXT("AbilitySystemComponent"));
    	AbilitySystemComponent->SetIsReplicated(true);
    	//...
    }

     

    class APACharacterBase : public AActor, public IAbilitySystemInterface
    {
    	//~ IAbilitySystemInterface 시작
    	/** 어빌리티 시스템 컴포넌트를 반환합니다. */
    	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
    	//~ IAbilitySystemInterface 끝
       
    	/** 어빌리티 시스템 컴포넌트입니다. 게임플레이 어트리뷰트 및 게임플레이 어빌리티를 사용하려면 필요합니다. */
    	UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Abilities")
    	UAbilitySystemComponent* AbilitySystemComponent;
    }

     

    void APACharacterBase::PossessedBy(AController * NewController)
    {
    	Super::PossessedBy(NewController);
    
    	if (AbilitySystemComponent)
    	{
    		AbilitySystemComponent->InitAbilityActorInfo(this, this);
    	}
    
    	// ASC MixedMode replication requires that the ASC Owner's Owner be the Controller.
    	SetOwner(NewController);
    }
    
    UAbilitySystemComponent* APACharacterBase::GetAbilitySystemComponent() const
    {
    	return AbilitySystemComponent;
    }

     

    void APAPlayerControllerBase::AcknowledgePossession(APawn* P)
    {
    	Super::AcknowledgePossession(P);
    
    	APACharacterBase* CharacterBase = Cast<APACharacterBase>(P);
    	if (CharacterBase)
    	{
    		CharacterBase->GetAbilitySystemComponent()->InitAbilityActorInfo(CharacterBase, CharacterBase);
    	}
    
    	//...
    }
    • ASC는 Server, Client 양쪽에서 모두 Initialize되어야 한다.
      • 또한 Controller가 Set(Possess)되고 나서 Initialize 되기를 원한다.
      • SinglePlay는 Server 파트에 대해서만 걱정을 하면 된다.
    • ASC가 설정된 Player는 각 파트에서 명시적으로 함수를 호출하여 Initialize를 해야 한다.
      • Server 파트: Pawn::PossessedBy()
      • Client 파트: APlayerController::AcknoledgePossession

고급 시나리오

  • 다른 Actor가 소유한 ASC를 사용하는 Actor를 구성할 수 있다.
    • ex) UPlayerState가 소유한 ASC를 사용하는 Pawn
  • 이를 위해 GetAbilitySystemComponent 함수가 Owner에서 ASC를 얻거나, 캐싱해야 한다.
  • 이 방식은 다음 속성이 있는 프로젝트에서 주로 발생한다.
    • Player가 제어하는 Actor가 리스폰을 하고, 그 과정에서 Game Ability System 정보가 필요한 경우
    • 장비나 Modular Machine, 신체 부위를 표현하기 위해 Actor가 자신에게 다른 Actor를 Attach하는 경우
    • 간단한 AI나 MOBA 게임
  • Attach 된 Actor의 Gameplay Ability System Interaction은 Parent의 ASC에 라우팅 할 수 있다.
    • 가장 간단하게 구현하는 방법은 Attach된 Actor의 GetAbilitySystemComponent가 Parent로 전달되는 것.
    • Actor 다른 ACtor에 Attach되거나 처리되는 동안 Cache 된 Pointer를 유지하면 Performance를 향상할 수 있다.
  • 단, ASC가 PlayerState에 있는 경우, PlayerState의 NetUpdateFrequency를 늘려야 한다.
  • Gameplay Ability System은 다수의 Actor가 하나의 Ability System Component를 공유하는 것은 지원한다.
    • 하지만 하나의 Actor가 다수의 Ability System Component를 가지는 것은 지원하지 않는다.
    • Actor의 Ability system Component에 변경사항을 적용하고 이를 얻을 때 모호함을 유발할 수 있기 때문.
 

Replicate Actor Properties In Unreal Engine | Unreal Engine 5.4 Documentation | Epic Developer Community

Learn how to replicate actor properties in Unreal Engine; including conditional replication, custom conditions, and object references.

dev.epicgames.com

ASC가 PlayerState에 있는 경우

  • 더보기
    // Server only
    void AGDHeroCharacter::PossessedBy(AController * NewController)
    {
    	Super::PossessedBy(NewController);
    
    	AGDPlayerState* PS = GetPlayerState<AGDPlayerState>();
    	if (PS)
    	{
    		// Set the ASC on the Server. Clients do this in OnRep_PlayerState()
    		AbilitySystemComponent = Cast<UGDAbilitySystemComponent>(PS->GetAbilitySystemComponent());
    
    		// AI won't have PlayerControllers so we can init again here just to be sure. No harm in initing twice for heroes that have PlayerControllers.
    		PS->GetAbilitySystemComponent()->InitAbilityActorInfo(PS, this);
    	}
    	
    	//...
    }

     

    // Client only
    void AGDHeroCharacter::OnRep_PlayerState()
    {
    	Super::OnRep_PlayerState();
    
    	AGDPlayerState* PS = GetPlayerState<AGDPlayerState>();
    	if (PS)
    	{
    		// Set the ASC for clients. Server does this in PossessedBy.
    		AbilitySystemComponent = Cast<UGDAbilitySystemComponent>(PS->GetAbilitySystemComponent());
    
    		// Init ASC Actor Info for clients. Server will init its ASC when it possesses a new Actor.
    		AbilitySystemComponent->InitAbilityActorInfo(PS, this);
    	}
    
    	// ...
    }
    •  ASC가 PlayerState에 있는 경우에는 명시적으로 Initialize 하는데 호출되는 함수가 달라진다.
      • Server: Pawn::PossessedBy()
      • Client: Pawn::Onrep_PlayerState()
    • 이 모든 과정은 Client에 PlayerState가 있다는 것을 상정하고 작업된다.
    • 만약 아래 로그가 발생하면, ASC가 Client에서 Initialize가 되지 않은 것이다.
      • LogAbilitySystem: Warning: Can't activate LocalOnly or LocalPredicted ability %s when not local!

'UE5 > GAS' 카테고리의 다른 글

[GAS] Ability Task  (0) 2024.05.16
[GAS] Gameplay Effect  (0) 2024.05.15
[GAS] Attribute Set  (1) 2024.05.14
[GAS] Gameplay Attribute  (0) 2024.05.13
[GAS] Gameplay Ability System 소개  (0) 2024.05.10

+ Recent posts