UnrealEngine5/프로젝트

[UE5] Blueprint 프로젝트를 C++로 (3) 마우스 클릭으로 캐릭터 이동하기

왹져박사 2025. 4. 22. 16:39

2025.04.21 - [UnrealEngine5/프로젝트] - [UE5] Blueprint 프로젝트를 C++로 만들어보기 (3) 마우스 커서 기반 이동하기

 

[UE5] Blueprint 프로젝트를 C++로 만들어보기 (3) 마우스 커서 기반 이동하기

1. 마우스 커서 보여주기 캐릭터 기능을 추가하기 전에, 컨트롤러에서 변경해야 할 점이 있다. 블루프린트로 만들었던 프로젝트에서는 마우스 커서의 input 위치를 바탕으로 이동했기 때문에,플

narmhye.tistory.com

 

캐릭터를 단순 Location 변환이 아닌, 이동을 시켜야 한다. 

Blueprint에서는, AIController를 가져와 AI MoveTo로 Location을 전달하여 이동시켰다. 

하지만, 지금 단계에서는 NavMeshVolume을 설정하지 않았기 때문에 MoveTo를 사용할 수 없다. 

임시로, 마우스 클릭 중에 해당 방향으로 이동하도록 설정하였다. 

 

마우스 커서 클릭 정보 HitResult는 PlayerController의

APlayerController::GetHitResultUnderCursorByChannel(ETraceTypeQuery TraceChannel, bool bTraceComplex, FHitResult& HitResult)를 통해 알 수 있다. 

 

이 GetHitResultUnderCursorByChannel를 타고 들어가다 WorldCollision.h를 보면,

아래와 같이 Raycast를 통하여 감지하는 것을 알 수 있다. 

 

그렇게 완성된 Move

void AMABCharacterPlayer::Move(const FInputActionValue& Value)
{
	// 마우스 커서 값 읽기.
	FHitResult HitResult;
	APlayerController* PlayerController = CastChecked<APlayerController>(GetController());
	PlayerController->GetHitResultUnderCursorByChannel(ETraceTypeQuery::TraceTypeQuery1, true, HitResult);

	// 커서 클릭 Location에서 캐릭터의 Location 빼기.
	FVector MoveDirection = HitResult.Location - GetActorLocation();

	float MovementVectorSize = 1.0f;
	MoveDirection.Normalize();

	UE_LOG(LogTemp, Log, TEXT("Move Direction x: %f, y: %f"), MoveDirection.X, MoveDirection.Y);

	// 입력에 따른 방향으로 이동하도록 입력 전달.
	AddMovementInput(MoveDirection, MovementVectorSize);
}

 

처음에는 HitResult.Location을 그대로 사용했더니, 처음에는 원하는 대로 이동하였지만

다시 이동하면 계속 같은 방향으로 이동하게 되는 현상이 보여졌다. 

당연한 결과였다. HitResult의 Location은 Character 중심의 Local 좌표계가 아니라 World 좌표계이기 때문이다. 

따라서, 이에 캐릭터의 현재 위치를 빼 주어 Location을 계산하였다. 

 

 

CharacterPlayer의 Move관련 내용. 

void AMABCharacterPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent);

	EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMABCharacterPlayer::Move);
}

void AMABCharacterPlayer::Move(const FInputActionValue& Value)
{
	// 마우스 커서 값 읽기.
	FHitResult HitResult;
	APlayerController* PlayerController = CastChecked<APlayerController>(GetController());
	PlayerController->GetHitResultUnderCursorByChannel(ETraceTypeQuery::TraceTypeQuery1, true, HitResult);

	// 커서 클릭 Location에서 현재 Location 빼기.
	FVector MoveDirection = HitResult.Location - GetActorLocation();

	float MovementVectorSize = 1.0f;
	MoveDirection.Normalize();

	UE_LOG(LogTemp, Log, TEXT("Move Direction x: %f, y: %f"), MoveDirection.X, MoveDirection.Y);

	// 캐릭터가 이동하는 방향에 맞게 컨트롤러 회전 설정.
	Controller->SetControlRotation(
		FRotationMatrix::MakeFromX(MoveDirection).Rotator()
	);

	// 입력에 따른 방향으로 이동하도록 입력 전달.
	AddMovementInput(MoveDirection, MovementVectorSize);
}

 

생성자에서 CharacterMovement의 OrientRotationToMovement를 활성화하면, 

캐릭터가 이동하는 방향으로 회전을 일치시켜줄 수 있다. 

	GetCharacterMovement()->bOrientRotationToMovement = true;