.h
UPROPERTY(VisibleDefaultsOnly, Category = Enemy)
class UAIPerceptionComponent* AIPerComp;
UPROPERTY(VisibleDefaultsOnly, Category = Enemy)
class UAISenseConfig_Sight* SightConfig;
UFUNCTION()
void OnSensed(const TArray<AActor*>& UpdatedActors);
.cpp : 생성자
AIPerComp = CreateDefaultSubobject<UAIPerceptionComponent>(TEXT("AI Perception Component"));
SightConfig = CreateDefaultSubobject<UAISenseConfig_Sight>(TEXT("Sight Config"));
SightConfig->SightRadius = 1250.0f; // 시각 반경
SightConfig->LoseSightRadius = 1280.0f; // 시각 상실 반경
SightConfig->PeripheralVisionAngleDegrees = 90.0f; // 주변 시야각
SightConfig->DetectionByAffiliation.bDetectEnemies = true; // 소속별 탐지 적
SightConfig->DetectionByAffiliation.bDetectFriendlies = true; // 소속별 탐지 팀
SightConfig->DetectionByAffiliation.bDetectNeutrals = true; // 소속별 탐지 중립
SightConfig->SetMaxAge(0.1f); //자극이 잊히기 까지의 시간 (0이면 잊지않음)
AIPerComp->ConfigureSense(*SightConfig);
AIPerComp->SetDominantSense(SightConfig->GetSenseImplementation());
AIPerComp->OnPerceptionUpdated.AddDynamic(this, &AEnemy::OnSensed);
주인공을 보면 따라가고 시야에서 벗어나면 다시 제 위치로 돌아옴
.h
PROPERTY(VisibleAnywhere, Category = Movement)
FRotator EnemyRotation;
UPROPERTY(VisibleAnywhere, Category = Movement)
FVector BaseLocation;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement)
FVector CurrentVelocity;
UPROPERTY(VisibleAnywhere, Category = Movement)
float MovementSpeed;
void SetNewRotation(FVector TargetPosition, FVector CurrentPosition);
bool BackToBaseLocation;
FVector NewLocation;
float DistanceSquared;
.cpp : 생성자
CurrentVelocity = FVector::ZeroVector;
MovementSpeed = 375.0f;
DistanceSquared = BIG_NUMBER; //32bit 부동 소수점의 최대값
.cpp : BeginStart()
BaseLocation = this->GetActorLocation();
.cpp : SetNewRotation()
FVector NewDirection = TargetPosition - CurrentPosition;
NewDirection.Z = 0.0f;
EnemyRotation = NewDirection.Rotation();
SetActorRotation(EnemyRotation);
.cpp : OnSensed
for (int i = 0; i < UpdatedActors.Num(); i++)
{
FActorPerceptionBlueprintInfo Info;
AIPerComp->GetActorsPerception(UpdatedActors[i], Info);
if (Info.LastSensedStimuli[0].WasSuccessfullySensed())
{
FVector dir = UpdatedActors[i]->GetActorLocation() - GetActorLocation();
dir.Z = 0.0f;
CurrentVelocity = dir.GetSafeNormal() * MovementSpeed;
SetNewRotation(UpdatedActors[i]->GetActorLocation(), GetActorLocation());
}
else
{
FVector dir = BaseLocation - GetActorLocation();
dir.Z = 0.0f;
if (dir.SizeSquared2D() > 1.0f)
{
CurrentVelocity = dir.GetSafeNormal() * MovementSpeed;
BackToBaseLocation = true;
SetNewRotation(BaseLocation, GetActorLocation());
}
}
.cpp : Tick()
if (!CurrentVelocity.IsZero())
{
NewLocation = GetActorLocation() + CurrentVelocity * DeltaTime;
if (BackToBaseLocation)
{
if ((NewLocation - BaseLocation).SizeSquared2D() < DistanceSquared)
{
DistanceSquared = (NewLocation - BaseLocation).SizeSquared2D();
}
else
{
CurrentVelocity = FVector::ZeroVector;
DistanceSquared = BIG_NUMBER;
BackToBaseLocation = false;
SetNewRotation(GetActorForwardVector(), GetActorLocation());
}
}
SetActorLocation(NewLocation);
}