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

Project_P 몬스터 HPBar 기능 추가

by k99812 2024. 12. 18.

HPBar 보완점


기존 HPBar는 몬스터가 벽뒤나 멀리 있어도 HPBar가 화면에 표시되어 위치를 알 수 있음

그래서 HPBar를 몬스터가 적을 인식할 때만 표시를 하려함

 

AI의 인식을 처리하는 AIController에 델리게이트를 생성하여 AI가 타겟을 인식하면 델리게이트를 통해 bool변수 true를 넘겨줌 타겟을 잊어버리면(null처리) bool변수 false를 넘겨줌

 

HPBar가 있는 CharacterGrunt 클래스에서 SetVisibility 함수를 통해 HPBar를 관리

 

APPAIController에서 델리게이트 생성 및 실행


헤더파일

DECLARE_DYNAMIC_DELEGATE_OneParam(FFindTargetDelegate, bool, bFindTarget);

UCLASS()
class PROJECT_P_API APPAIController : public AAIController
{

	~~~

	FFindTargetDelegate FindTargetDelegate;

	~~~
};

 

  • DECLARE_DYNAMIC_DELEGATE_OneParam으로 델리게이트 정의
  • FFindTargetDelegate FindTargetDelegate;
    • 델리게이트 생성

 

PerceptionSensedSight

void APPAIController::PerceptionSensedSight(APawn* PerceptionedPawn)
{
	UE_LOG(LogTemp, Log, TEXT("ActorPerceptionUpdated : %s"), *PerceptionedPawn->GetName());

	UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(PerceptionedPawn);
	if (ASC)
	{
		GetBlackboardComponent()->SetValueAsObject(BBKEY_TARGET, PerceptionedPawn);
		AActor::SetActorTickEnabled(true);
		FindTargetDelegate.ExecuteIfBound(true);
	}
}

 

  • FindTargetDelegate.ExecuteIfBound(true);
    • AI의 시각센서로 타겟이 업데이트 되는 함수에서 추가적으로 델리게이트를 실행

 

ActorPerceptionForgetUpdated

void APPAIController::ActorPerceptionForgetUpdated(AActor* Actor)
{
	APawn* PerceptionedPawn = Cast<APawn>(Actor);

	if (PerceptionedPawn && PerceptionedPawn->GetController()->IsPlayerController())
	{
		UE_LOG(LogTemp, Log, TEXT("ActorPerceptionForgetUpdated : %s"), *Actor->GetName());

		APawn* Target = Cast<APawn>(GetBlackboardComponent()->GetValueAsObject(BBKEY_TARGET));
		if (PerceptionedPawn == Target)
		{
			GetBlackboardComponent()->SetValueAsObject(BBKEY_TARGET, nullptr);
			AActor::SetActorTickEnabled(false);
			FindTargetDelegate.ExecuteIfBound(false);
		}
	}
}

 

  • FindTargetDelegate.ExecuteIfBound(false);
    • 타겟이 잊혀질때 실행되는 함수에서 델리게이트 실행

 

ResetTarget

void APPAIController::ResetTarget()
{
	APawn* Target = Cast<APawn>(GetBlackboardComponent()->GetValueAsObject(BBKEY_TARGET));
	if (Target)
	{
		UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Target);

		if (ASC)
		{
			FGameplayTagContainer Tag(PPTAG_CHARACTER_ISDEAD);
			if (ASC->HasAnyMatchingGameplayTags(Tag))
			{
				GetBlackboardComponent()->SetValueAsObject(BBKEY_TARGET, nullptr);
				AActor::SetActorTickEnabled(false);
				FindTargetDelegate.ExecuteIfBound(false);
			}
		}
	}
}

 

  • 플레이어가 죽어서 타겟을 리셋할때 실행되는 함수에서도 델리게이트를 실행

 

APPGASCharacterGrunt 에서 기능 구현


헤더파일

UCLASS()
class PROJECT_P_API APPGASCharacterGrunt : public APPGASCharacterNonPlayer
{
	GENERATED_BODY()
	
	~~~

	UFUNCTION()
	void FoundTargetCallback(bool bFoundTarget);
};

 

  • UFUNCTION()
    void FoundTargetCallback(bool bFoundTarget);
    • 다이나믹 델리게이트여서 UFUNCTION()매크로 부착
    • 콜백함수 선언

 

생성자

APPGASCharacterGrunt::APPGASCharacterGrunt()
{
	~~~

//HPBar 설정
	HpBar = CreateDefaultSubobject<UPPGASWidgetComponent>(TEXT("Widget"));
	HpBar->SetupAttachment(GetMesh());
	HpBar->SetRelativeLocation(FVector(0.0f, 0.0f, 175.0f));

	static ConstructorHelpers::FClassFinder<UUserWidget> HpBarWidgetRef(TEXT("/Game/Project_P/Blueprint/UI/WBP_HpBar.WBP_HpBar_C"));
	if (HpBarWidgetRef.Class)
	{
		~~~
		HpBar->SetVisibility(false);
	}

	~~~
}

 

HpBar->SetVisibility(false);로 처음엔 HPBar를 비활성화

 

FoundTargetCallback

void APPGASCharacterGrunt::FoundTargetCallback(bool bFoundTarget)
{
	HpBar->SetVisibility(bFoundTarget);
}

 

SetVisibility를 들어오는 변수에 따라 설정