본문 바로가기

언리얼엔진/FirstProject

적캐릭터 충돌시 회전하기 C++

블루프린트로 구현한 추적하기를 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