UE4

[UE4] 마우스휠로 카메라 줌(Zoom)기능 구현하기

Honey Badger 2022. 10. 21. 21:22

 

구현 방법

 

  1. 먼저 프로젝트세팅>입력 으로 들어가서 액션매핑에 ZoomIn과 ZoomOut을 만들어준다.

 

 

2. 설정한 입력 세팅을 캐릭터 클래스의 SetupPlayerInputComponent()함수에서 원하는 함수와 바인딩 시켜준다.

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

	// 설정한 입력 세팅을 Pawn의 함수와 Binding시키기.
	
	PlayerInputComponent->BindAction(TEXT("ZoomIn"), EInputEvent::IE_Pressed, this, &AMyCharacter::ZoomIn);
	PlayerInputComponent->BindAction(TEXT("ZoomOut"), EInputEvent::IE_Pressed, this, &AMyCharacter::ZoomOut);
}

 

 

 

3. 위에서 바인딩한 함수에 다음과 같이 기능을 구현해주면 끝! 

void AMyCharacter::ZoomIn()
{
	SpringArm->TargetArmLength = FMath::Clamp<float>(SpringArm->TargetArmLength-30.0f, 150.0f, 800.0f);
}

void AMyCharacter::ZoomOut()
{
	SpringArm->TargetArmLength = FMath::Clamp<float>(SpringArm->TargetArmLength+30.0f, 150.0f, 800.0f);
}

 

선형보간으로 부드럽게 움직이기

    Zoom이 일어날때마다 스프링암 값이 원활하게 변화하는 것을 확인했다면, 에디터처럼 뚝뚝끊기게 변화하는 것이 아닌 흔한 rpg게임 카메라처럼 부드럽게 확대 축소가 가능하도록 코드를 변경해보자. 스프링암의 목적값을 변수로 둔 다음 Zoom함수들에서 이 목적값을 변화시켜준다. 그리고 매 프레임마다 호출되는 Tick함수에서 FMath::Lerp함수를 사용하여 "현재 스프링암 길이(SpringArm->TargetArmLength)"와 "스프링암 목적값(ExpectedSpringArmLength)" 사이를 선형보간해주면 된다. 

 

 

1. 먼저 변수를 선언해준다. UPROPERTY()에 대한 내용은 추후 자세히 다루도록 하자.

UPROPERTY(VisibleInstanceOnly, BlueprintReadOnly, Category = SpringArm, Meta = (AllowPrivateAccess = true))
float ExpectedSpringArmLength; //스프링암 길이 목표값.

 

 

2. 위에서 정의한 ZoomIn, out 함수를 수정해준다.

void AMyCharacter::ZoomIn()
{
	ExpectedSpringArmLength = FMath::Clamp<float>(ExpectedSpringArmLength - 150.0f, 150.0f, 800.0f);
}

void AMyCharacter::ZoomOut()
{
	ExpectedSpringArmLength = FMath::Clamp<float>(ExpectedSpringArmLength + 150.0f, 150.0f, 800.0f);
}

 

 

3. Tick()에서 선형보간 시켜준다. if문의 내용은 절댓값으로 현재스프링암 길이와 스프링암목적값의 차이가 KINDA_SMALL_NUMBER보다 큰경우만 선형보간해준다는 내용이다. 이렇게 하지 않으면 아주 작은 값까지 0이 될때까지 선형보간해 성능저하가 우려될 수 있다. 

// Called every frame
void AMyCharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	
	//줌 선형보간
	if (FMath::Abs(SpringArm->TargetArmLength - ExpectedSpringArmLength) > KINDA_SMALL_NUMBER)
	{
		SpringArm->TargetArmLength = FMath::Lerp(SpringArm->TargetArmLength, ExpectedSpringArmLength, 0.05f);
	}	
}

 

삽질의 시간

  사실 언리얼 공부를 시작한지 어느 덧 반년이 지났지만, 그저 책이나 유튜브, 구글에 나오는 코드를 이해하려고만 애썼지 내 스스로 어떤 기능을 구현한 적이 없었다. 그래서 이번에 간단한 코드라도 온전히 내 힘으로 짜보고자 마우스 휠로 카메라를 줌인 줌아웃 시키는 기능을 구현해보았다. (수많은 삽질끝에 조금 당황했다 코드가 이렇게까지 간단할 줄 몰랐으니..)

 

  1. 먼저 프로젝트 세팅으로 들어가서 인풋값을 세팅해주었다. 처음에 액션매핑이 아닌 축매핑을 썼는데 마우스 휠을 딱 떠올렸을 때 버튼같은 클릭이 아니니 당연히 축이라고 생각했던 것 같다. 하지만 결론은 액션매핑이었다. 

 

  2. 액션매핑으로 마우스휠 up과 down을 Zoom이라는 매핑으로 넣어주었는데 이또한 미스.. 이건 내가 아직 인풋값 세팅에 대해 완벽히 이해를 못했기에 일어난 실수였다. ZoomIn과 ZoomOut을 따로 만들어 그에 따른 함수도 따로 만들어주었다. 

 

3. FMath::Clamp<> 실수.. 그래도 반년동안 공부했다고 Clamp를 호기롭게 썼는데 <>안에 int를 쓰고, Clamp의 반환값을 어디에도 할당 안하는 등 자잘한 삽질이 이어졌지만.. 수많은 공격에도 다시 일어나 할일하는 벌꿀오소리처럼 나도 수많은 삽질 끝에 드디어 해냈다!!!! 

 

  사실 코드 보면 뭘 해냈다기엔 민망한 두줄짜리 결과지만.. 엔진을 이해하고 책과, 구글링, 유튜브 남의 코드 어떠한것도 보지 않은채 완성한 첫 언리얼 기능이라 넘 뿌듯했다. 오늘의 이 기억을 발판삼아 앞으로 더 어렵고 복잡한 기능도 결국 구현해내리라 다짐해본다...!!