본문 바로가기
포트폴리오 제작/Project_P

Project_P 공격 판정 구현(3) Trace 어빌리티 태스크 생성

by k99812 2024. 9. 6.

Trace 어빌리티 태스크 생성


 

AbilkityTask를 상속받아 PPAT_Trace 클래스를 생성

 

PPAT_Trace 헤더파일


#include "CoreMinimal.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "PPAT_Trace.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FTraceResultDelegate, const FGameplayAbilityTargetDataHandle&, TargetDataHandle);

/**
 * 
 */
UCLASS()
class PROJECT_P_API UPPAT_Trace : public UAbilityTask
{
	GENERATED_BODY()
	
public:
	UPPAT_Trace();

	UFUNCTION(BlueprintCallable, Category = "Ability|Tasks", meta = (DisplayName = "JumpAndWaitForLanding",
		HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE"))
	static UPPAT_Trace* CreateTask(UGameplayAbility* OwnerAbility, TSubclassOf<class APPTA_Trace> TargetActorClass);

	virtual void Activate() override;

	virtual void OnDestroy(bool bInOwnerFinished) override;

	void SpawnAndInitializeTargetActor();

	void FinalizeTargetActor();

	UPROPERTY(BlueprintAssignable)
	FTraceResultDelegate OnComplete;

protected:
	void TargetDataReadyCallback(const FGameplayAbilityTargetDataHandle& DataHandle);

	UPROPERTY()
	TSubclassOf<class APPTA_Trace> TargetActorClass;

	UPROPERTY()
	TObjectPtr<class APPTA_Trace> SpawnedTargetActor;
};

 

  • DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam
    (FTraceResultDelegate, const FGameplayAbilityTargetDataHandle&, TargetDataHandle);
    • 어빌리티 태스크가 완료되면 오너GA에게 알려줄 델리게이트
    • TA가 완료시 AT에게 콜백 그후 AT가 오너GA에게 알려줌
    • const FGameplayAbilityTargetDataHandle&, TargetDataHandle 변수는 TA에서 판정결과를 저장하고 잇음
      TA 델리게이트에서 최초로 선언되어 전해짐
  • UPPAT_Trace();
    • 생성자
  • static UPPAT_Trace* CreateTask(UGameplayAbility* OwnerAbility, TSubclassOf<class APPTA_Trace> TargetActorClass);
    • AT를 생성시 필수로 만들어야 하는 함수
    • static함수로 다른 외부함수에서 호출할 수 있고 AT를 생성해주는 함수
    • 매개변수로 OwnerGA, 초기화에 필요한 변수들을 추가적으로 받음
  • virtual void Activate() override;
    • 부모함수 UAbilityTask의 부모함수 UGameplayTask에서 선언된 함수
    • OwnerGA에서 ReadyForActivation함수를 실행하면 발동되는 함수
    • 해당함수에서 TargetActor를 생성
  • virtual void OnDestroy(bool bInOwnerFinished) override;
    • AT가 종료될때 실행되는 함수
    • 생성한 TargetActor를 파괴하는데 사용
  • void SpawnAndInitializeTargetActor();

    void FinalizeTargetActor();
    • TargetActor를 지연생성으로 생성해 2개의 함수로 생성을 나눔
  • FTraceResultDelegate OnComplete;
    • 오너GA에게 AT 종료를 알려줄 델리게이트
  • void TargetDataReadyCallback(const FGameplayAbilityTargetDataHandle& DataHandle);
    • 생성한 TargetActor가 공격판정결과를 알려줄 콜백함수
  • TSubclassOf<class APPTA_Trace> TargetActorClass;
    • 생성할 TargetActorClass를 저장할 변수
  • TObjectPtr<class APPTA_Trace> SpawnedTargetActor;
    • 생성한 TargetActor를 관리할 변수

 

Cpp 파일


생성자

생성자에선 설정할게 없음

 

CreateTask

UPPAT_Trace* UPPAT_Trace::CreateTask(UGameplayAbility* OwnerAbility, TSubclassOf<class APPTA_Trace> TargetActorClass)
{
	UPPAT_Trace* NewTask = NewAbilityTask<UPPAT_Trace>(OwnerAbility);

	NewTask->TargetActorClass = TargetActorClass;

	return NewTask;
}

 

AbilityTask를 생성 후 생성한 인스턴스를 반환해주는 함수

  • UPPAT_Trace* NewTask = NewAbilityTask<UPPAT_Trace>(OwnerAbility);
    • NewAbilityTask 함수를 사용하여 인스턴스 생성
  • NewTask->TargetActorClass = TargetActorClass;
    • 함께 매개변수로 들어온 TargetActorClass를 초기화
  • return NewTask;
    • 생성한 AT를 리턴

 

Activate

void UPPAT_Trace::Activate()
{
	Super::Activate();

	SpawnAndInitializeTargetActor();
	FinalizeTargetActor();

	SetWaitingOnAvatar();
}

 

어빌리티 태스크 실행함수

  • Super::Activate();
    • 부모함수 실행
  • SpawnAndInitializeTargetActor();
    • 지연생성을 해 SpawnedTargetActor에 인스턴스를 생성후 필요한 변수 초기화 및 델리게이트 바인드를 함
  • FinalizeTargetActor();
    • 최종적으로 TA를 트랜스폼을 지정하여 생성하는 함수
  • SetWaitingOnAvatar();
    • 어빌리티 태스크가 실행중이라고 알려주는 함수
    • NotifyAbilityTaskWaitingOnAvatar 함수를 실행하여 ASC에게 필요한 로직을 실행하게됨

 

OnDestroy

void UPPAT_Trace::OnDestroy(bool bInOwnerFinished)
{
	if (SpawnedTargetActor)
	{
		SpawnedTargetActor->Destroy();
	}

	Super::OnDestroy(bInOwnerFinished);
}

 

어빌리티 태스크가 없어질때 생성한 TA도 같이 없애주는 역활을 함

  • if (SpawnedTargetActor)
    • SpawnedTargetActor->Destroy();
      • 스폰한 타겟액터가 있으면 Destory실행
  • Super::OnDestroy(bInOwnerFinished);
    • 부모함수 실행

 

SpawnAndInitializeTargetActor

void UPPAT_Trace::SpawnAndInitializeTargetActor()
{
	SpawnedTargetActor = Cast<APPTA_Trace>(Ability->GetWorld()->SpawnActorDeferred<AGameplayAbilityTargetActor>(TargetActorClass, FTransform::Identity,
		nullptr, nullptr, ESpawnActorCollisionHandlingMethod::AlwaysSpawn));

	if (SpawnedTargetActor)
	{
		SpawnedTargetActor->SetShowDebug(true);
		SpawnedTargetActor->TargetDataReadyDelegate.AddUObject(this, &UPPAT_Trace::TargetDataReadyCallback);
	}
}

 

  • SpawnedTargetActor = Cast<APPTA_Trace>
    (Ability->GetWorld()>SpawnActorDeferred<AGameplayAbilityTargetActor>(~~~));
    • SpawnedTargetActor에 SpawnActorDeferred(지연생성, FinishSpawning을 호출해야 생성완료)로 인스턴스 생성
    • SpawnActorDeferred<T>(생성할 액터 클래스 정보, 트랜스폼, 오너액터, Instigator, 스폰한 액터 콜리전 핸들방법)
  • if (SpawnedTargetActor)
    • 인스턴스가 있으면
    • SpawnedTargetActor->SetShowDebug(true);
      • 디버그 true로 설정
    • SpawnedTargetActor->TargetDataReadyDelegate.AddUObject(this, &UPPAT_Trace::TargetDataReadyCallback);
      • 타겟액터 델리게이트에 콜백함수 바인드

 

FinalizeTargetActor

void UPPAT_Trace::FinalizeTargetActor()
{
	UAbilitySystemComponent* ASC = AbilitySystemComponent.Get();
	if (ASC)
	{
		const FTransform SpawnTransform = ASC->GetAvatarActor()->GetTransform();
		SpawnedTargetActor->FinishSpawning(SpawnTransform);

		ASC->SpawnedTargetActors.Push(SpawnedTargetActor);
		SpawnedTargetActor->StartTargeting(Ability);
		SpawnedTargetActor->ConfirmTargeting();
	}
}

 

  • UAbilitySystemComponent* ASC = AbilitySystemComponent.Get();
    • 부모함수 UAiblityTask에 선언 되어있는 AbilitySystemComponent를 통해 ASC 가져오기
    • Owner GA를 소유하고있는 액터의 ASC를 가져옴
  • if (ASC)
    • ASC가 있으면
    • const FTransform SpawnTransform = ASC->GetAvatarActor()->GetTransform();
      • 최종적으로 소유하고있는 오너액터의 ASC를 통해서 트랜스폼을 가져옴
    • SpawnedTargetActor->FinishSpawning(SpawnTransform);
      • 얻은 트랜스폼을 FinishSpawning에 넣어주어 생성할 위치를 지정한후 TA 스폰 마무리
      • FinishSpawning을 실행함으로 TA가 생성됨
    • ASC->SpawnedTargetActors.Push(SpawnedTargetActor);
      • ASC에 생성된 타겟엑터 넣어줌
    • SpawnedTargetActor->StartTargeting(Ability);
      • 스폰한 타겟액터를 실행 인자로 오너GA를 넣어줌
    • SpawnedTargetActor->ConfirmTargeting();
      • 타겟팅 확정

 

TargetDataReadyCallback

void UPPAT_Trace::TargetDataReadyCallback(const FGameplayAbilityTargetDataHandle& DataHandle)
{
	if (ShouldBroadcastAbilityTaskDelegates())
	{
		OnComplete.Broadcast(DataHandle);
	}

	EndTask();
}

 

타겟액터의 판정이 끝나면 호출되는 콜백함수

  • if (ShouldBroadcastAbilityTaskDelegates())
    • ShouldBroadcastAbilityTaskDelegates함수를 통해 델리게이트를 Brodcast를 해줘야되는지 확인가능
    • OnComplete.Broadcast(DataHandle);
      • 델리게이트 Brodcast
  • EndTask();
    • 어빌리티 태스크 종료