블루프린트로 구현한 추적하기를 C++로 만들어 본다.
충돌감지를 위한 캡슐 컴포넌트 추가
public:
UPROPERTY(VisibleAnywhere, Category = "Fire")
class UCapsuleComponent* capsuleComp;
충돌체 델리게이트 선언
UFUNCTION() //충돌체 델리게이트선언
void OnEnemyCollisionCompOverlap(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
montage animation레퍼런스를 선언한다. 이건 플레이어 클래스와 동일하므로 추가할 필요는 없다.
UPROPERTY(EditAnywhere, Category = "Animation")
UAnimMontage* attackAnimMontage; //공격애니메이션
Enemy.cpp 생성에서 구현
capsuleComp = CreateDefaultSubobject< UCapsuleComponent>(TEXT("CapsuleCollision"));
capsuleComp->SetupAttachment(GetCapsuleComponent());
capsuleComp->SetRelativeScale3D(FVector(1, 1, 1));
충돌을 감지할 capsuleComp->OnComponentBeginOverlap.AddDynamic() Delegate 선
void AEnemy::BeginPlay()
{
Super::BeginPlay();
capsuleComp->OnComponentBeginOverlap.AddDynamic(this,&AEnemy::OnEnemyCollisionCompOverlap);
PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
//niagaraFX = GetComponentByClass<UNiagaraComponent>();
//niagaraFX->SetVisibility(false);
}
델리게이션 함수 구현 충돌시 플레이어가 아니면 90도 회전하고 플레이어일 경우 Montage_Play로 공격애니메이션을 실행한다.
void AEnemy::OnEnemyCollisionCompOverlap(UPrimitiveComponent* OverlappedComponent,
AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
ATPSPlayer* Player = Cast<ATPSPlayer>(OtherActor);
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
if (Player) {
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Magenta, FString::Printf(TEXT("OnEnemyCollisionCompOverLapCpp %s"), *OtherActor->GetFName().ToString()));
AnimInstance->Montage_Play(attackAnimMontage);
}
else {
const FRotator _cr = GetActorRotation();
//GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Magenta, FString::Printf(TEXT("OnEnemyCollisionCompOverLapCpp %f %f %f"), (double)_cr.Pitch, (double)_cr.Yaw, (double)_cr.Roll)); //%f %f %f, (double)_cr.Pitch, (double)_cr.Yaw, (double)_cr.Roll)
const FRotator _newRotator = FRotator(_cr.Pitch, _cr.Yaw + 90.f, _cr.Roll);
//const FRotator _cr = GetActorRotation();
//GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Magenta, TEXT("OnEnemyCollisionCompOverLapCpp%f %f %f", (double)_cr.Pitch, (double)_cr.Yaw , (double)_cr.Roll));
SetActorRotation(_newRotator);
}
}
적이 플레이어를 따라갈 Move()함수를 만들어 Tick() 에 넣어준다. orientRotation을 꺼주자
void AEnemy::Move(float DeltaTime) // const FInputActionValue& Value)
{
PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
FVector _pLocation = PlayerPawn->GetActorLocation();
FVector _myLocation = GetActorLocation();
const FVector _newDir = _pLocation - _myLocation;
SetActorRotation(_newDir.Rotation()); //orientRotation을 켜주면 안넣어줘도 된다.
// get forward vector
const FVector Direction = FRotationMatrix(_newDir.Rotation()).GetUnitAxis(EAxis::X);
AddMovementInput(Direction);
}
이렇게도 만들어 봤지만 이건 NG다
void AEnemy::Move(float DeltaTime) // const FInputActionValue& Value)
{ //캐릭터의 회전 처리가 잘 안됨
PlayerPawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
FVector _pLocation = PlayerPawn->GetActorLocation();
FVector _myLocation = GetActorLocation();
const FVector _newDir = _pLocation - _myLocation;
SetActorRotation(_newDir.Rotation());
if (Controller)
{
moveDirection.Y = _newDir.GetSafeNormal().Y;
moveDirection.X = _newDir.GetSafeNormal().X;
}
}
'언리얼엔진 > FirstProject' 카테고리의 다른 글
LineTrace 참조 (0) | 2023.11.17 |
---|---|
시선방향으로 발사하기 참조 (0) | 2023.11.16 |
인공지능 적 만들기 (0) | 2023.11.15 |
무기 장착하기 (1) | 2023.11.14 |
마우스휠로 줌하기 (1) | 2023.11.14 |