Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

게임 개발 메모장

[ UE5 ] GameplayAbilitySystem : AbilityTask 본문

언리얼 엔진/기능

[ UE5 ] GameplayAbilitySystem : AbilityTask

Dev_Moses 2024. 1. 10. 10:56

 

 


AbilityTask 정의

GameplayAbility는 한 프레임에서만 실행됩니다. 이는 그 자체로는 많은 유연성을 허용하지 않습니다. 시간이 지남에 따라 발생하거나 나중에 특정 시점에 발동된 델리게이트에 응답해야 하는 액션을 수행하려면 AbilityTask라는 잠재 액션을 사용합니다.

 

GAS에는 다양한 AbilityTask가 기본으로 제공

  • 루트모션 소스로 캐릭터를 이동하는 작업
  • 애니메이션 몽타주 재생 작업
  • 어트리뷰트 변경에 대응하기 위한 작업
  • GameplayEffect 변경에 대응하기 위한 작업
  • 플레이어 입력에 응답하기 위한 작업
  • 그 외

UAbilityTask 생성자는 게임 전체에 하드코딩된 최대 1,000개의 AbilityTask 동시 실행을 강제합니다. RTS 게임처럼 월드에 수백 명의 캐릭터가 동시에 등장할 수 있는 게임의 GameplayAbility를 디자인할 때는 이 점을 염두에 두어야 합니다.


커스텀 AbilityTask

종종 커스텀 AbilityTask(C++)를 직접 만들게 될 것입니다. 

 

샘플 프로젝트에는 두 개의 커스텀 AbilityTask가 포함되어 있습니다:

  1. PlayMontageAndWaitForEvent는 기본 PlayMontageAndWait와 WaitGameplayEvent AbilityTasks의 조합입니다. 이를 통해 애니메이션 몽타주가 애니메이션 노티파이에서 GameplayEvent를 시작했던 GameplayAbility로 다시 전송할 수 있습니다. 이를 사용하여 애니메이션 몽타주 도중 특정 시간에 액션을 트리거할 수 있습니다.
  2. WaitReceiveDamage는 소유자 액터가 피해를 받을 때까지 기다립니다. 패시브 방어구 중첩은 영웅이 피해를 받으면 GameplayAbility가 방어구 중첩을 제거합니다.

 

AbilityTask는 다음으로 구성됩니다:

  • AbilityTask의 새 인스턴스를 생성하는 정적 함수입니다.
  • AbilityTask가 목적을 완료할 때 브로드캐스트되는 위임자
  • 주 작업을 시작하고 외부 델리게이트에 바인딩하는 등의 작업을 수행하는 Activate() 함수입니다.
  • 바인딩한 외부 델리게이트를 포함한 정리를 위한 OnDestroy() 함수입니다.
  • 바인딩한 외부 델리게이트에 대한 콜백 함수입니다.
  • 멤버 변수 및 내부 도우미 함수
💡Note: AbilityTask는 한 가지 유형의 출력 델리게이트만 선언할 수 있습니다. 매개변수 사용 여부에 관계없이 모든 출력 델리게이트는 이 유형이어야 합니다. 사용하지 않는 델리게이트 매개변수에는 기본값을 전달하세요.

 

 

AbilityTask는 소유 GameplayAbility를 실행 중인 클라이언트 또는 서버에서만 실행되지만, AbilityTask 생성자에서 bSimulatedTask = true; 를 설정하고 가상 void InitSimulatedTask(UGameplayTasksComponent& InGameplayTasksComponent); 를 오버라이드하고 리플리케이트할 멤버 변수를 설정하여 시뮬레이션 클라이언트에서 실행되도록 설정할 수 있습니다. 이 방법은 모든 동작 변경을 리플리케이트하지 않고 전체 동작을 시뮬레이션하려는 이동 AbilityTask와 같은 드문 상황에서만 유용합니다. 모든 루트모션 소스 AbilityTask가 이 작업을 수행합니다. 예시로 AbilityTask_MoveToLocation.h/.cpp를 참조하세요.

AbilityTask 생성자에서 bTickingTask = true; 를 설정하고 가상 void TickTask(float DeltaTime); 를 오버라이드하면 AbilityTask가 틱할 수 있습니다. 이 함수는 프레임에 걸쳐 값을 매끄럽게 처리해야 할 때 유용합니다. 예제로 AbilityTask_MoveToLocation.h/.cpp를 참조하세요.


AbilityTask 사용

C++에서 AbilityTask를 생성하고 활성화하려면 (GDGA_FireGun.cpp 에서) 다음과 같이 합니다:

UGDAT_PlayMontageAndWaitForEvent* Task = UGDAT_PlayMontageAndWaitForEvent::PlayMontageAndWaitForEvent(this, NAME_None, MontageToPlay, FGameplayTagContainer(), 1.0f, NAME_None, false, 1.0f);
Task->OnBlendOut.AddDynamic(this, &UGDGA_FireGun::OnCompleted);
Task->OnCompleted.AddDynamic(this, &UGDGA_FireGun::OnCompleted);
Task->OnInterrupted.AddDynamic(this, &UGDGA_FireGun::OnCancelled);
Task->OnCancelled.AddDynamic(this, &UGDGA_FireGun::OnCancelled);
Task->EventReceived.AddDynamic(this, &UGDGA_FireGun::EventReceived);
Task->ReadyForActivation();

 

 

블루프린트에서는 AbilityTask에 대해 생성한 블루프린트 노드를 사용하기만 하면 됩니다. ReadyForActivation()을 호출할 필요가 없습니다. 엔진/소스/편집기/GameplayTask 편집기/비공개/K2Node_LatentGameplay태스크 호출.cpp에서 자동으로 호출됩니다. 또한 K2Node_LatentGameplayTaskCall은 AbilityTask 클래스에 BeginSpawningActor() 및 FinishSpawningActor()가 있는 경우 자동으로 호출합니다(AbilityTask_WaitTargetData 참조). 다시 말하자면, K2Node_LatentGameplayTaskCall 은 블루프린트에 대한 오토매직 마법만 수행합니다. C++에서는 ReadyForActivation(), BeginSpawningActor(), FinishSpawningActor()를 수동으로 호출해야 합니다.

 

 

AbilityTask를 수동으로 취소하려면 블루프린트(비동기 태스크 프록시라고 함) 또는 C++에서 AbilityTask 오브젝트에서 EndTask() 를 호출하면 됩니다.


루트 모션 소스 AbilityTask

GAS에는 CharacterMovementComponent에 연결된 루트 모션 소스를 사용하여 넉백, 복잡한 점프, 당기기, 돌진 등 시간 경과에 따라 캐릭터를 움직일 수 있는 AbilityTask가 포함되어 있습니다.

💡Note: 루트모션소스 어빌리티태스크 예측은 엔진 버전 4.19 및 4.25 이상에서 작동합니다. 엔진 4.20~4.24 버전에서는 예측에 버그가 있지만, 어빌리티 태스크는 약간의 수정만 거치면 멀티플레이어에서 여전히 그 기능을 수행하며 싱글플레이어에서도 완벽하게 작동합니다. 4.25의 예측 수정 사항을 커스텀 4.20-4.24 엔진으로 체리피킹할 수 있습니다.