Dev5 Enemy 첫 배치, 카메라 회전 제한
Enemy.h
어그로(인식)범위와 전투 범위
해당 범위에 오버랩 되었을 때, 오버랩 해제됐을 때 OverlapBegin, End
ai컨트롤러 생성
타겟에게로 이동하는 함수 MoveToTarget()
UCLASS()
class YARO_API AEnemy : public ACharacter
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
AEnemy();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Movement")
EEnemyMovementStatus EnemyMovementStatus;
FORCEINLINE void SetEnemyMovementStatus(EEnemyMovementStatus Status) { EnemyMovementStatus = Status; }
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AI")
class USphereComponent* AgroSphere;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AI")
USphereComponent* CombatSphere;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AI")
class AAIController* AIController;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UFUNCTION()
virtual void AgroSphereOnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION()
virtual void AgroSphereOnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
UFUNCTION()
virtual void CombatSphereOnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION()
virtual void CombatSphereOnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
void MoveToTarget(class AMain* Target);
};
Enemy.cpp
생성자에서 인식범위, 전투 범위 설정
AEnemy::AEnemy()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
AgroSphere = CreateDefaultSubobject<USphereComponent>(TEXT("AgroSphere"));
AgroSphere->SetupAttachment(GetRootComponent());
AgroSphere->InitSphereRadius(400.f);
CombatSphere = CreateDefaultSubobject<USphereComponent>(TEXT("CombatSphere"));
CombatSphere->SetupAttachment(GetRootComponent());
CombatSphere->InitSphereRadius(200.f);
}
BeginPlay()에서 컨트롤러 캐스트하고 할당
void AEnemy::BeginPlay()
{
Super::BeginPlay();
AIController = Cast<AAIController>(GetController());
AgroSphere->OnComponentBeginOverlap.AddDynamic(this, &AEnemy::AgroSphereOnOverlapBegin);
AgroSphere->OnComponentEndOverlap.AddDynamic(this, &AEnemy::AgroSphereOnOverlapEnd);
CombatSphere->OnComponentBeginOverlap.AddDynamic(this, &AEnemy::CombatSphereOnOverlapBegin);
CombatSphere->OnComponentEndOverlap.AddDynamic(this, &AEnemy::CombatSphereOnOverlapEnd);
}
AddDynamic( UserObject, FuncName ) : 다이내믹 멀티-캐스트 델리게이트에서 AddDynamic() 호출을 위한 헬퍼 매크로. 함수 이름 문자열을 자동 생성.
이라고 합니다… 흠..
인식 범위에 오버랩되었을 때
타켓으로 이동하는 함수 실행
void AEnemy::AgroSphereOnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor)
{
AMain* Main = Cast<AMain>(OtherActor);
if (Main)
{
MoveToTarget(Main);
}
}
}
MoveToTarget()
void AEnemy::MoveToTarget(AMain* Target)
{
SetEnemyMovementStatus(EEnemyMovementStatus::EMS_MoveToTarget);
if (AIController)
{
FAIMoveRequest MoveRequest;
MoveRequest.SetGoalActor(Target);
MoveRequest.SetAcceptanceRadius(25.0f);
FNavPathSharedPtr NavPath;
AIController->MoveTo(MoveRequest, &NavPath);
/** 어그로(인식)범위(구 콜리전)에 충돌했을 때 어떤 경로를 따라서 몬스터가 따라오는지 확인 가능
auto PathPoints = NavPath->GetPathPoints();
for (auto Point : PathPoints)
{
FVector Location = Point.Location;
UKismetSystemLibrary::DrawDebugSphere(this, Location, 25.8f, 8, FLinearColor::Green, 10.f, 1.5f);
}
*/
}
}
ai controller의 moveTo함수 이용
몬스터 Grux 블루프린트 클래스
인식범위 전투범위 구 콜리전 확인 가능
플레이어 컨트롤러에서 카메라 회전 제한 설정
void AMainPlayerController::BeginPlay()
{
Super::BeginPlay();
this->PlayerCameraManager->ViewPitchMin = -50.f; // 세로회전 위
this->PlayerCameraManager->ViewPitchMax = 10.f; //아래
}
아 참, 카메라 콜리전에 부딪히면 플레이어한테 가까이 오는 것 없앰
Main.cpp
// but npc, enemy들도 여기에 콜리전으로 해당되어 게임 플레이가 불편하므로 콜리전 테스트 끔
CameraBoom->bDoCollisionTest = false;
영상으로 확인 - 몬스터 애니메이션과 이동, 카메라 회전 제한
다음 할 것 : 몬스터 공격 등등, 카메라 줌인/줌아웃