코드로 ai 조작

REWELLGOM·2025년 5월 31일

Unreal5

목록 보기
24/26
void AEnemyBase::BeginPlay()
{
	Super::BeginPlay();

	EnemyController = Cast<AAIController>(GetController());
	MoveToTarget(PatrolTarget);
	
	if (PawnSensing)
	{
		PawnSensing->OnSeePawn.AddDynamic(this, &AEnemyBase::PawnSeen);
	}
	

	AttachDefaultWeapon();
}

void AEnemyBase::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	
	if (EnemyState > EEnemyState::EES_Patrolling)
	{
		CheckCombatTarget();
	}
	else
	{
		CheckPatrolTarget();
	}
	
}


void AEnemyBase::PawnSeen(APawn* SeenPawn)
{
	if (EnemyState == EEnemyState::EES_Chasing) return;
	if (SeenPawn->ActorHasTag(FName("ShooterCharacter"))) //cast쓰기엔 매초 부르는건 좋지않음 그래서 tag시스템 사용
	{
		EnemyState = EEnemyState::EES_Chasing;
		//GetWorldTimerManager().ClearTimer(PatrollTimer) 순찰을 넣을거면 이거써야함 그래야 플레이어 따라감
		GetCharacterMovement()->MaxWalkSpeed = 150.f;
		MoveToTarget(SeenPawn);
		UE_LOG(LogTemp, Warning, TEXT("Chasing U"));
	}

}

void AEnemyBase::MoveToTarget(AActor* Target)
{
	if (!IsValid(EnemyController) || !IsValid(Target)) return;

	FAIMoveRequest MoveRequest;
	MoveRequest.SetGoalActor(Target);
	MoveRequest.SetAcceptanceRadius(15.f);
	FNavPathSharedPtr NavPath;
	EnemyController->MoveTo(MoveRequest, &NavPath);
	TArray<FNavPathPoint> PathPoints = NavPath->GetPathPoints();

	//디버깅
	for (auto& Point : PathPoints)
	{
		const FVector& Location = Point.Location;
		DrawDebugSphere(GetWorld(), Location, 12.f, 12, FColor::Green, false, 10.f);
	}
}

bool AEnemyBase::InTargetRange(AActor* Target, double Radius)
{
	const double DistanceToTarget = (Target->GetActorLocation() - GetActorLocation()).Size();

	return DistanceToTarget <= Radius;
}

void AEnemyBase::CheckCombatTarget()
{
	if (CombatTarget)
	{
		if (!InTargetRange(CombatTarget, CombatRadius))
		{
			// 타겟이 멀어졌을때 없을때
			CombatTarget = nullptr;
			EnemyState = EEnemyState::EES_Patrolling;
			GetCharacterMovement()->MaxWalkSpeed = 400.f;
			MoveToTarget(PatrolTarget);
			UE_LOG(LogTemp, Warning, TEXT("Shes Gone"));
		}
		else if (!InTargetRange(CombatTarget, AttackRadius) && EnemyState != EEnemyState::EES_Chasing)
		{
			//공격 범위 벗어나면
			EnemyState = EEnemyState::EES_Chasing;
			GetCharacterMovement()->MaxWalkSpeed = 300.f;
			MoveToTarget(CombatTarget);
			UE_LOG(LogTemp, Warning, TEXT("Out OF Range"));
		}
		else if (InTargetRange(CombatTarget, CombatRadius) && EnemyState != EEnemyState::EES_Attacing)
		{
			//공격범위안의 적 공격
			EnemyState = EEnemyState::EES_Attacing;
			//attack montage
			UE_LOG(LogTemp, Warning, TEXT("ATK!"));
		}
	}

}

void AEnemyBase::CheckPatrolTarget()
{
	if (InTargetRange(PatrolTarget, PatrolRadius) && EnemyController)
	{
		EnemyState = EEnemyState::EES_Patrolling;

		FAIMoveRequest MoveRequest;
		MoveRequest.SetGoalActor(PatrolTarget);
		MoveRequest.SetAcceptanceRadius(15.f);
		EnemyController->MoveTo(MoveRequest);
	}

}
profile
코테는 초딩한테 이해하기 쉽게 문제 해설해주는거다

0개의 댓글