ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [UE5 RPG] 7. ์ „ํˆฌ ์ž…๋ ฅ์„ ํ†ตํ•ด GA ํ™œ์„ฑํ™”ํ•˜๊ธฐ : GameAbility, GamePlayTag, ์–ด๋นŒ๋ฆฌํ‹ฐ ๋””๋ฒ„๊ทธ ์ฐฝ ์ผœ๊ธฐ
    UnrealEngine/SomedayProject 2025. 11. 11. 14:36


    ๐Ÿ“Œ Someday Proejct ๊ฐœ๋ฐœ์ผ์ง€ ์‹œ๋ฆฌ์ฆˆ

    ๋”๋ณด๊ธฐ
     

     


     

    ์ด๋ฒˆ์—๋Š” ์ „ํˆฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ค๊ณ 

    ์ธํ’‹์ด๋ž‘ ์—ฐ๊ฒฐํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค

     

     

    https://hyun2and.tistory.com/38

     

    [UE5 RPG] 4. ๊ฑท๊ธฐ, ์ ํ”„ ์ด๋™ ์กฐ์ž‘ : GameplayAbilities, ์ ํ”„ Animation Blueprint

    ๐Ÿ“Œ Someday Proejct ๊ฐœ๋ฐœ์ผ์ง€ ์‹œ๋ฆฌ์ฆˆ ๋”๋ณด๊ธฐ"> ์• ๋‹ˆ๋ฉ”์ด์…˜์— Ablitiy ๋ฅผ ์—ฐ๊ฒฐํ•ด์„œ ์“ด๋‹ค๋Š”๋“ฏํ•˜๋‹ค๋‚˜์ค‘์„ ์œ„ํ•ด ๋ฏธ๋ฆฌ ์„ธํŒ…ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ธฐโœ๏ธ GameplayAbilities ๋ฅผ ์“ฐ๋ ค๋ฉดSomedayProject.Build.cs ์— PublicDependencyModuleN

    hyun2and.tistory.com

    ์ง€๋‚œ๋ฒˆ์— ์–ด๋นŒ๋ฆฌํ‹ฐ๋ฅผ ๋ชจ๋“ˆ์— ์ถ”๊ฐ€ํ•˜๋Š”๊ฑด ๋ฏธ๋ฆฌ ํ•ด๋‘์—ˆ๋‹ค

     

    ๐Ÿ””์ „ํˆฌ ์ด๋ฒคํŠธ ๋…ธํ‹ฐ

    Lyra ์˜ GA ํ™œ์„ฑํ™” ๊ณผ์ •

    1. IMC ๋ฅผ ํ†ตํ•ด ์ž…๋ ฅ๊ณผ IA๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค. HeroComponent ๋‚˜ Chahracter ์— ๋„ฃ์–ด์„œ Mapping ํ•ด์คŒ
    2. LyraInputConfig๋ฅผ ํ†ตํ•ด IA์™€ InputTag.Weapon.NormalAttack ๋ฅผ ๋ฐ”์ธ๋“œํ•œ๋‹ค
      1. LyraInputConfig๋Š” LyraPawnData ์•ˆ์—. FLyraInputAction ๋กœ Tag์™€ Action์„ ๋ฌถ์–ด๋†“์Œ
    3. ULyraHeroComponent::InitializePlayerInput ์—์„œ ULyraInputComponent::AddInputMappings ํ˜ธ์ถœ
      1. InputComponent ๊ฐ€ ์ค€๋น„๋œ ๋‹ค์Œ ํƒ€์ด๋ฐ. PawnExtensionComp ์˜ OnPawnReadyToInitialize_RegisterAndCall(FSimpleMulticastDelegate::FDelegate::CreateUObject(this, &ThisClass::OnPawnReadyToInitialize)); ์— ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ๊ฑธ์—ˆ๋‹ค
      2. ๋๋‚˜๊ณ ๋‚˜๋ฉด ๋ชจ๋“  Actions ๋“ค์„ ๋ฐ”์ธ๋“œ
        1. InputConfig ์•ˆ์— ๋“ฑ๋ก๋œ Tag-Action ๋“ค์„ ๋ชจ๋‘ ์—ฐ๊ฒฐํ•˜๋Š” ์ฝ”๋“œ
        2. ์—ฌ๊ธฐ์„œ๋Š” ๋”ฑํžˆ Handles ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋Š” ์•Š๋‹ค
      3. LyraIC->BindAbilityActions(InputConfig, this, &ThisClass::Input_AbilityInputTagPressed, &ThisClass::Input_AbilityInputTagReleased, /*out*/ BindHandles);
      4. ๋‚ด๋ถ€์ ์œผ๋กœ ๊ฒฐ๊ตญ์—” BindAction(Action.InputAction, ETriggerEvent::Triggered, Object, PressedFunc, Action.InputTag) ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค
    4. ์ธํ’‹์ด ๋“ค์–ด์˜ค๋ฉด ALyraPlayerController::PostProcessInput ์—์„œ ์ธํ’‹์ฒ˜๋ฆฌ
      1. InputTag.Weapon.NormalAttack ๊ฐ€ ์ผœ์ง„๋‹ค
      2. void ALyraPlayerController::PostProcessInput(const float DeltaTime, const bool bGamePaused) { if (ULyraAbilitySystemComponent* LyraASC = GetLyraAbilitySystemComponent()) { LyraASC->ProcessAbilityInput(DeltaTime, bGamePaused); } Super::PostProcessInput(DeltaTime, bGamePaused); }
    5. ASC::ProcessAbilityInput ๋‚ด๋ถ€์—์„œ TryActivateAbility๋ฅผ ์‹คํ–‰
    6. ASC์—์„œ ์ด์ „์— ๋“ฑ๋ก๋œ InputTag๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋งค์นญ๋œ GA๋ฅผ ํ™œ์„ฑํ™”ํ•œ๋‹ค
    7. GA ์•ˆ์— Activation OwnedTags ๋ฅผ ์„ค์ •ํ•˜๋ฉด ์ด GA๊ฐ€ ํ™œ์„ฑํ™”๋  ๋•Œ Movement.NormalAttack ๊ฐ€ ์ผœ์ง„๋‹ค
    8. ์ดํ›„ ๊ณต๊ฒฉ ์ฒ˜๋ฆฌ์™€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ํ™œ์„ฑํ™” ํ•ด์•ผํ•จ

    https://lemonyun.tistory.com/148

    ์ž˜ ์ •๋ฆฌํ•ด์ฃผ์‹  ๋ถ„์ด ์žˆ์–ด์„œ ์ฐธ๊ณ 

     

    ํ•„์š”ํ•œ ๊ณผ์ •

    1. IMC์™€ IA ์ƒ์„ฑ
    2. HeroComponent::InitializePlayerInput ์—์„œ IA์™€ InputTag ์—ฐ๊ฒฐ
      1. InputConfig๋Š” ์ผ๋‹จ ๋งŒ๋“ค์ง€ ์•Š๊ณ . HeroComponent ์•ˆ์— ์ง์ ‘ ๋„ฃ๋„๋ก ํ•˜์ž
      2. @TODO ๋‚˜์ค‘์— ํ•„์š”ํ•œ ๊ฒฝ์šฐ PawnData, InputConfig ์ƒ์„ฑ → DefaultData ๋งŒ ์ •์˜ํ•˜์ž
      3. ์ผ๋‹จ HeroComponent BeginPlay ์•ˆ์— ๋ฐ”๋กœ ๋„ฃ๋„๋ก ํ•˜์ž
    3. InputTag ์™€ GA๋ฅผ ์—ฐ๊ฒฐ

     

    ๐Ÿ†• ์ธํ’‹ ์ƒ์„ฑํ•˜๊ธฐ

    1. Triggers ์ถ”๊ฐ€

    InputTag ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ๊ทธ๋Ÿผ ์ € InputTag๊ฐ€ ์ผœ์ง€๋Š” ์ˆœ๊ฐ„์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ์ด GA ๊ฐ€ ํ™œ์„ฑํ™”๋œ๋‹ค

     

     

    2. Tags ์„ธํŒ…

     

    UGamePlayAbility ๋‚ด๋ถ€์— ์—ฌ๋Ÿฌ ํƒœ๊ทธ๊ฐ’์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด์žˆ๋Š”๋ฐ

     

     

    ์ง€๊ธˆ ๋‚˜์˜ ์ƒํ™ฉ์—์„  Input ์ด ๋“ค์–ด์™”์„ ๋•Œ Movement.NormalAttack ์„ ์ผœ์ฃผ๋ฉด ๋˜๋Š” ์ƒํ™ฉ์ด๋‹ˆ๊นŒ

    ํ™œ์„ฑํ™” ์†Œ์œ  ํƒœ๊ทธ๋ฅผ ์ผœ์„œ, ์บ๋ฆญํ„ฐ์— ์ด ๋ฌด๋ธŒ๋จผํŠธ ํƒœ๊ทธ๋ฅผ ๋ถ€์ฐฉ์‹œํ‚ค๋ฉด ๋œ๋‹ค

     

    3. IA ์ƒ์„ฑ, IMC ์—ฐ๊ฒฐ

     

    IA์— ์™ผ์ชฝ๋งˆ์šฐ์Šคํด๋ฆญ ์ถ”๊ฐ€ํ•˜๊ณ , IMC์—๋„ ๋„ฃ์–ด์คŒ

     

     

    + ๋ผ์ด๋ธŒ์ฝ”๋”ฉ ์—๋Ÿฌ

    ๋”๋ณด๊ธฐ



    ๋ผ์ด๋ธŒ์ฝ”๋”ฉ ์—๋Ÿฌ๊ฐ‘์ž๊ธฐ ์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋œจ๋ฉด์„œ ๋นŒ๋“œ๊ฐ€ ์•ˆ๋˜๋Š”๋ฐ๋ผ์ด๋ธŒ์ฝ”๋”ฉ ์ธ์ฝ”๋”ฉ ๊นจ์ ธ์„œ ์ž˜์“ฐ๊ธฐ ์–ด๋ ต๋‹ค

    ์ผ๋‹จ ๋นŒ๋“œ๋ฅผ ๋‹ค์‹œ ํ•ด๋ณด์ž → ๋นŒ๋“œ ๋‹ค์‹œํ–ˆ๋”๋‹ˆ ํ•ด๊ฒฐ๋จ.. Live ์ฝ”๋”ฉ์ด๋ž‘ ์ผ๋ฐ˜ ๋””๋ฒ„๊น…์ด๋ž‘ ์„ž์ด๋ฉด ์ด๋ ‡๊ฒŒ ๋ฌธ์ œ๊ฐ€ ๋˜๋‚˜

     

     

    4. BindAction ์œผ๋กœ ์ธํ’‹ ๋“ค์–ด์™”์„ ๋•Œ ์ผœ์งˆ Tag ๋งคํ•‘ํ•˜๊ธฐ

    • ์บ๋ฆญํ„ฐ์— HeroComponent ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , HeroComponent BeginPlay ์—์„œ BindAction ์„ ์‹คํ–‰ํ•œ๋‹ค
    • ๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•œ ์• ๋“ค๋งŒ ๊ณต๊ฒฉ์ด๋‚˜ ์ด๋Ÿฐ ํ‚ค ์ž…๋ ฅ์„ ๋ฐ›์•„์•ผ ํ•ด์„œ HeroComponent ์—์„œ ์ดˆ๊ธฐํ™”ํ•˜๋Š”๊ฒŒ ๋งž์„๊ฒƒ๊ฐ™์€๋ฐ
    • HeroComp ๋Š” ์บ๋ฆญํ„ฐ ์ฝ”๋“œ์—์„œ ์ƒ์„ฑํ•ด์ฃผ๊ณ ์žˆ์–ด์„œ ๋ฐ”์ธ๋“œ๋ฅผ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ๊ณณ์— ์ €์žฅํ•ด๋‘ฌ์•ผํ•จ
      • SPDefaultData PrimaryAsset ์„ ์ƒ์„ฑํ•ด์„œ ๊ทธ ์•ˆ์— ๋„ฃ์–ด์ฃผ์ž

     

    +EditDefaultsOnly ์„ค์ •

    DataAsset์— ๋„ฃ์—ˆ์œผ๋‚˜ ์ˆ˜์ •์ด ์•ˆ๋ผ์„œ ํ™•์ธํ•ด๋ณด๋‹ˆ UPROPERTY๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์Œ

    DefaultsOnly, InstanceOnly, Anywhere ํ‚ค์›Œ๋“œ์˜ ์ฐจ์ด๊ฐ€ ๊ถ๊ธˆํ–ˆ๋Š”๋ฐ ์ด ๋ธ”๋กœ๊ทธ์—์„œ ์ž˜ ์„ค๋ช…ํ•ด์ฃผ์‹ฌ

    https://darkcatgame.tistory.com/62

    ๋‚˜์˜ ๊ฒฝ์šฐ์—” ์–ด์ฐจํ”ผ ์‹ค์ œ ๋Ÿฐํƒ€์ž„์ค‘์— ์ˆ˜์ •ํ•  ๊ฑด ์•„๋‹ˆ๋‹ˆ๊นŒ EditDefaultsOnly ๋กœ ์ˆ˜์ •ํ•˜์ž

    USTRUCT(BlueprintType)
    struct FSPInputActionBindData
    {
        GENERATED_BODY()
    
    public:
        UPROPERTY(EditDefaultsOnly)
        TObjectPtr<UInputAction> InputAction;
    
        UPROPERTY(EditDefaultsOnly)
        FGameplayTag InputTag;
    };

     

     

    ์ž˜ ๋ณด์ด๋Š”๊ฒƒ์„ ํ™•์ธ

     

     

    ๊ฒŒ์ž„ ์‹คํ–‰ํ•˜๊ณ  IMC ์— ๋“ฑ๋ก๋œ ์ขŒํด๋ฆญ ๋ชจ์…˜์„ ํ•˜๋ฉด IA๊ฐ€ ํ˜ธ์ถœ

    ๊ฑฐ๊ธฐ์— HeroComponent ์— ๋“ฑ๋ก๋œ ๋ฐ”์ธ๋“œ ํ•จ์ˆ˜๊นŒ์ง€ ์ž˜ ํ˜ธ์ถœ๋˜๊ณ  ์žˆ๋‹ค

     

    5. PressedFunc ์ธํ’‹ ๋“ค์–ด์™”์„ ๋•Œ GA ์ผœ์ฃผ๊ธฐ

    ๊ฐ€์žฅ ํ—ท๊ฐˆ๋ ธ๋˜ ๊ฐœ๋…์€ Granted ์™€ Activate ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ

    • ๋ฌด๊ธฐ๋ฅผ ์žฅ์ฐฉํ–ˆ์„ ๋•Œ GA_Weapon๋ฅผ GiveAbility ํ˜ธ์ถœํ•ด์„œ ๋„ฃ์—ˆ๋‹ค = ์ด ๋•Œ์˜ ์ƒํƒœ๋Š” ๊ทธ๋ƒฅ Granted
    • ์‹ค์ œ Active ๋œ ์ƒํƒœ๋Š” ์ดํ›„์— TryActivateAbility ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ
    ํ•ญ๋ชฉ ์„ค๋ช…
    Give/Remove Give๋Š” ํ•œ ๋ฒˆ(์บ๋ฆญํ„ฐ ์ดˆ๊ธฐํ™” ์‹œ)๋งŒ ํ•˜๊ณ , Remove๋Š” ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค (์ฃฝ๊ฑฐ๋‚˜ ํŠน์ • ์ƒํ™ฉ).
    Activate/End ํ‚ค๋ฅผ ๋ˆ„๋ฅผ ๋•Œ๋งˆ๋‹ค Activate๋˜๊ณ , ๊ณต๊ฒฉ์ด ๋๋‚˜๋ฉด End Ability๋กœ ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.
    ๊ณต๊ฒฉ ์ฒ˜๋ฆฌ ์œ„์น˜ ๊ณต๊ฒฉ์˜ ๋ชจ๋“  ๋กœ์ง (์• ๋‹ˆ๋ฉ”์ด์…˜, ํŒ์ •, ํ”ผํ•ด)์€ Gameplay Ability ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ๋˜๋Š” C++ ํด๋ž˜์Šค ๋‚ด๋ถ€์— ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.
    ํ”ผํ•ด ๊ตฌํ˜„ ํ”ผํ•ด๋Š” Gameplay Effect๋ฅผ ํ†ตํ•ด Attribute Set์˜ ์ฒด๋ ฅ(Health) ๊ฐ’์„ ์ˆ˜์ •ํ•˜์—ฌ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    void USPHeroComponent::OnInputActionTriggered(const FInputActionValue& Value, FGameplayTag InputTag)
    {
        LOG_INFO(LogSPDefault, TEXT("USPHeroComponent::OnInputActionTriggered"));
    
        ASomedayProjectCharacter* SPCharacter = GetPawn<ASomedayProjectCharacter>();
        if (SPCharacter == nullptr)
        {
            return;
        }
    
        if (const APawn* Pawn = GetPawn<APawn>())
        {
            if (USPAbilitySystemComponent* ASC = SPCharacter->GetSPAbilitySystemComponent())
            {
                FGameplayTagContainer InputTagContainer;
                InputTagContainer.AddTag(InputTag);
    
                **ASC->TryActivateAbilitiesByTag(InputTagContainer);**
            }
        }
    }

    Lyra์—์„œ๋Š” PlayerController ๋„ ๋‹ค๋…€์˜ค๊ณ  ํ•˜๋˜๋ฐ ์ผ๋‹จ ์ œ์ผ ๋‹จ์ˆœํ•œ ๋ชจ์–‘์œผ๋กœ ๋งŒ๋“ค์–ด๋ณด์ž

    6. GA ํ™œ์„ฑํ™”๋จ

     

    ์ด๋Ÿฐ ๊ณผ์ •์œผ๋กœ Tag๊ฐ€ ์ถ”๊ฐ€๋˜๊ณ  Ability๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

     

    โœ… ์ถ”๊ฐ€๋œ ํƒœ๊ทธ ํ™•์ธํ•˜๊ธฐ

     

    ‘ ๋ฅผ ๋ˆ„๋ฅด๊ณ  ๋””๋ฒ„๊ทธ๋ฅผ ์ผ  ๋‹ค์Œ 3๋ฒˆ์„ ๋ˆ„๋ฅด๋ฉด Abilities ๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

    Movement.NormalAttack ํƒœ๊ทธ๊ฐ€ ์ถ”๊ฐ€๋๋‹ค

    Tag ์ œ๊ฑฐ ๊ณผ์ •์„ ์•ˆ๊ฐ€์ ธ์„œ ๊ณ„์† ์ค‘์ฒฉ๋˜๋Š”์ค‘

    void USPGameAbility_WeaponDefault::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
    {
        Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
    
        UE_LOG(LogSPDefault, Log, TEXT("USPGameAbility_WeaponDefault::ActivateAbility"));
        //์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹คํ–‰
        //ํ”ผ๊ฒฉ ํŒ์ • ์‹คํ–‰
    
        EndAbility(Handle, ActorInfo, ActivationInfo, false, false);
    }

     

    Gameplay Ability System (GAS)์˜ ์ฒ ํ•™์€ ์–ด๋นŒ๋ฆฌํ‹ฐ๊ฐ€ ์ž์‹ ์˜ ์ƒ๋ช…์ฃผ๊ธฐ(Lifecycle)๋ฅผ ์Šค์Šค๋กœ ๊ด€๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    ์–ด๋นŒ๋ฆฌํ‹ฐ ๋‚ด๋ถ€์—์„œ End ์ฒ˜๋ฆฌ๋ฅผ ์ง์ ‘ ํ•ด์ฃผ๊ณ , ์ด๊ฑธ ASC ์—์„œ ๋…ธํ‹ฐ๋ฐ›์•„์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค

     

     

    ๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด GA ๊ฐ€ ํ™œ์„ฑํ™”๋œ๊ฒƒ์„ ์•Œ์ˆ˜์žˆ๋‹ค

    GA๋Š” ๊ฒจ์šฐ ํ™œ์„ฑํ™”ํ–ˆ๊ณ .. ์ด๋‹ค์Œ์€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹คํ–‰์„ ํ•ด๋ณด์ž

     

     

     

    728x90
Designed by Tistory.