[Unreal] 조준선을 마우스 위치로 이동하기

박민주·2022년 8월 28일
0

Unreal

목록 보기
5/29

목표

  • 일반적인 FPS처럼 조준선이 화면 중앙에 있는 것이 아니라, 마우스 위치로 있게 하는 것
  • 플레이어가 조준선을 향해 회전

원래 플레이어가 마우스의 이동에 따라 회전하고 있었다.
커서를 보이도록 하기 위해 PlayerController를 새로 만들어서 설정했더니
커서가 나름의 조준점 역할을 할 수 있었으나 그 상태론 플레이어가 회전하질 않아서 다른 방법을 찾았다.

고민하다가 공식 튜토리얼 중 조준점 만드는 걸 가져다가
그 조준점의 위치를 Canvas의 중앙이 아닌 마우스 위치로 설정해주었다.

마우스 위치는
FVector2D mousePosition = UWidgetLayoutLibrary::GetMousePositionOnViewport(GetWorld());
로 받아올 수 있었다.

그리고 DrawHUD 함수가 매 틱마다 불려지는 것 같아서
그 곳에서 조준선 위치를 정해주었다.

CrosshairHUD.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "CrosshairHUD.generated.h"

UCLASS()
class PROJECTF_API ACrosshairHUD : public AHUD
{
	GENERATED_BODY()
	
public:
	virtual void DrawHUD() override;

protected:
	UPROPERTY(EditDefaultsOnly)
	UTexture2D* CrosshairTexture;
};

CrosshairHUD.cpp

#include "CrosshairHUD.h"
#include "Engine/Canvas.h"
#include <Runtime/UMG/Public/Blueprint/WidgetLayoutLibrary.h>

void ACrosshairHUD::DrawHUD()
{
	Super::DrawHUD();

	if (CrosshairTexture)
	{
		FVector2D mousePosition = UWidgetLayoutLibrary::GetMousePositionOnViewport(GetWorld());

		// 텍스처 중심이 캔버스 중심에 맞도록 텍스처의 크기 절반 만큼 오프셋을 줍니다.
		FVector2D CrossHairDrawPosition(mousePosition.X - (CrosshairTexture->GetSurfaceWidth() * 0.5f), mousePosition.Y - (CrosshairTexture->GetSurfaceHeight() * 0.5f));

		// 중심점에 조준선을 그립니다.
		FCanvasTileItem TileItem(CrossHairDrawPosition, CrosshairTexture->Resource, FLinearColor::White);
		TileItem.BlendMode = SE_BLEND_Translucent;
		Canvas->DrawItem(TileItem);
	}
}

부록..

다음 방법으론 Player Controller 새로 만들어서 커서 보이게 하는 것..
Player Controller를 새로 만들면 BP_GameMode에서 Player Controller Class를 바꿔주어야 합니다

그리고 아래 코드로 커서 방향으로 플레이어가 회전하게 했다


void ATPSPlayer2::Move()
{
	// 플레이어 이동 처리
	// 등속 운동
	direction = FTransform(GetControlRotation()).TransformVector(direction);
	AddMovementInput(direction);
	direction = FVector::ZeroVector;

	if (GetWorld()->GetFirstPlayerController()->bShowMouseCursor == false)
	{
		return;
	}

	// 플레이어 회전 처리
	// - 마우스 위치로 회전해야 함 
	FHitResult Hit;
	GetWorld()->GetFirstPlayerController()->GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, false, Hit);

	FVector ToTarget = Hit.Location - playerMeshComp->GetComponentLocation();
	FRotator LookAtRotation = FRotator(0.f, UKismetMathLibrary::ClampAxis(ToTarget.Rotation().Yaw), 0.f);
	
	SetActorRotation(LookAtRotation);

}

중간에 UKismetMathLibrary::ClampAxis(ToTarget.Rotation().Yaw) 이거는 안해줬을 때
플레이어가 이상하게 회전하는 것 같아서 0~360으로 ClampAxis 해주었다.

profile
Game Programmer

0개의 댓글