Unreal GAS (4) - AbilitySystemComponent, AttributeSet

wnsduf0000·2025년 12월 1일

Unreal_GAS

목록 보기
4/34
  • 생성자에서 AbilitySystemComponent, AttributeSet 구성

    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "AbilitySystemInterface.h"
    #include "AuraCharacterBase.generated.h"
    
    class UAbilitySystemComponent;
    class UAttributeSet;
    
    UCLASS(Abstract)
    class AURA_API AAuraCharacterBase : public ACharacter, public IAbilitySystemInterface
    {
    	GENERATED_BODY()
    
    public:
    	AAuraCharacterBase();
    
    	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
    	UAttributeSet* GetAttributeSet() const { return AttributeSet; }
    
    protected:
    	virtual void BeginPlay() override;
    
    	UPROPERTY(EditAnywhere, Category = "Combat")
    	TObjectPtr<USkeletalMeshComponent> WeaponSkeletalMesh;
    
    	UPROPERTY()
    	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
    
    	UPROPERTY()
    	TObjectPtr<UAttributeSet> AttributeSet;
    };
    • AuraCharacterBase에서 UAbilitySystemComponent 및 UAttributeSet 변수를 생성함.

    • GAS는 AbilitySystemComponent에 편하게 접근할 수 있도록 IAbilitySystemInterface를 제공하는데, 이는 AbilitySystemInterface를 include 해주면 사용할 수 있음.

      • 단, build.csPublicDependencyModuleNamesGameplayAbilities 를 추가해주어야 함.
    • AttributeSet의 경우는 인터페이스를 제공하지는 않으나, 임의로 함수를 생성함.

      AAuraEnemyCharacter::AAuraEnemyCharacter()
      {
      	GetMesh()->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
      
      	AbilitySystemComponent = CreateDefaultSubobject<UAuraAbilitySystemComponent>("AbilitySystemComponent");
      	AbilitySystemComponent->SetIsReplicated(true);
      
      	AttributeSet = CreateDefaultSubobject<UAuraAttributeSet>("AttributeSet");
      }
    • Aura 프로젝트의 경우, 플레이어는 PlayerState에, 몬스터는 AuraEnemyCharacter 상속 폰 자체에 AbilitySystemComponent와 AttributeSet를 포함할 예정이므로,
      AuraCharacterBase에서 선언한 AbilitySystemComponent와 AttributeSet는 AuraEnemyCharacter의 생성자에서만 생성해주고, AuraPlayerCharacter에서는 하지 않았음.

    • 플레이어의 경우, AbilitySystemComponent와 AttributeSet 세팅을 위한 위와 같은 구성을 AuraPlayerState에서 해주면 됨.

  • Gameplay Effect Replication Mode

    Full, Mixed, Minimal의 이름만으로는 Full이 멀티플레이 용도의 Replication이고,
    Minimal로 갈수록 싱글플레이용으로 생각하기 쉬운데 그 반대임.
    네트워크 대역폭의 총량을 고려하여 생각하면 될 것 같음.

  • Init Ability Actor Info

    • AbilitySystemComponent는 Ability Actor에 대한 정보를 포함하도록 설계되어 있음.

      	// AbilitySystemComponent.h
      	
      	private:
      	/** The actor that owns this component logically */
      	UPROPERTY(ReplicatedUsing = OnRep_OwningActor)
      	TObjectPtr<AActor> OwnerActor;
      
      	/** The actor that is the physical representation used for abilities. Can be NULL */
      	UPROPERTY(ReplicatedUsing = OnRep_OwningActor)
      	TObjectPtr<AActor> AvatarActor;
    • OwnerActor는 AbilitySystemComponent를 실제로 소유한 액터를 의미하며,
      AvatarActor는 해당 AbilitySystemComponent에 의해 실제 영향을 받는 월드 내 액터를 의미.
      - 예를 들어, 현재 설계 상 AuraEnemyCharacter는 OwnerActor와 AvatarActor가 동일함.
      AuraEnemyCharacter 자체가 컴포넌트를 소유하며, 그 자체가 영향을 받기 때문.

      하지만 플레이어의 경우, 컴포넌트를 소유한 것은 AuraPlayerState이지만,
      영향을 받는 플레이어의 투영, 즉 캐릭터는 AuraPlayerCharacter이므로,
      OwnerActor와 AvatarActor가 다른 것임.
    • AbilitySystemComponent는 OwnerActor와 AvatarActor를 설정하기 위한 InitAbilityActorInfo(AActor* InOwnerActor, AActor* InAvatarActor) 함수를 제공함.
      호출의 적절한 시기는 액터가 컨트롤러에 의해 possession 된 이후임.

    • 플레이어

      • 폰 자체에 컴포넌트가 부착된 경우 (OwnerActor와 AvatarActor가 같은 경우),
        이미 존재하는 컨트롤러에 의해 소유된 것을 알기 위한 함수를 사용하면 되는데,
        서버의 경우 PossessedBy, 클라이언트의 경우 AcknowledgePossession 임.

      • OwnerActor와 AvatarActor가 다른 경우,
        서버의 경우 PossessedBy 를 그대로 사용해도 되지만,
        클라이언트의 경우 OnRep_PlayerState 를 사용해야 함.
        (ASC가 PlayerState에 존재하므로, AvatarActor가 컨트롤러에 소유되는 것 뿐만 아니라 PlayerState 또한 유효한 것을 확인해야 하기 때문.)
        - OnRep_PlayerState는 RepNotify 함수 중 하나로,
        RepNotify 함수는 Replication의 결과로 인해 호출되는 함수라고 보면 됨.
        PlayerState가 서버에서 클라이언트로 Replicate되면, 그 결과로 호출되는 함수임.

        ```cpp
        void AAuraPlayerCharacter::PossessedBy(AController* NewController)
        {
            Super::PossessedBy(NewController);
        
            /** Init Ability Actor Info for Server */
            InitAbilityActorInfo();
        }
        
        void AAuraPlayerCharacter::OnRep_PlayerState()
        {
            Super::OnRep_PlayerState();
        
            // Init Ability Actor Info for Client
            InitAbilityActorInfo();
        }
        
        void AAuraPlayerCharacter::InitAbilityActorInfo()
        {
            AAuraPlayerState* AuraPlayerState = GetPlayerState<AAuraPlayerState>();
            check(AuraPlayerState);
        
            AuraPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(AuraPlayerState, this);
            AbilitySystemComponent = AuraPlayerState->GetAbilitySystemComponent();
            AttributeSet = AuraPlayerState->GetAttributeSet();
        }
        ```
        
        - Mixed Replication Mode의 경우, OwnerActor의 소유자(Owner)가 반드시 Controller여야 함.
        Pawn이나 PlayerState가 OwnerActor인 경우, 이들은 자동적으로 Controller를 Owner로 갖도록 설정되지만, 그렇지 않은 액터가 OwnerActor라면, 반드시 해당 액터에서 SetOwner()를 호출하여 Controller가 Owner가 되도록 설정해주어야 함.
  • AI 컨트롤 캐릭터

    • Aura 프로젝트에서는 캐릭터 자체가 ASC를 소유하고,
      유효한 컨트롤러와 ASC를 소유할 것이 분명하므로 Beginplay 에서 호출하면 됨.
      ```cpp
      void AAuraEnemyCharacter::BeginPlay()
      {
      	Super::BeginPlay();
      
      	AbilitySystemComponent->InitAbilityActorInfo(this, this);
      }
      ```
profile
저는 게임 개발자로 일하고 싶어요

0개의 댓글