Unreal - 달리 줌 (Dolly - Zoom)

2026. 1. 25. 19:26·Unreal 프로젝트 다이어리/두번째 프로젝트

미리보기

구현내용

플레이어는 포탈을 통해 맵 간 이동을 수행하며,

이동시 Level Sequence의 Dolly - Zoom 카메라 기법을 활용하여

포탈에 빨려 들어가는 듯한 시각적 연출을 구현

 

달리 줌 (Dolly - Zoom) 이란?

일명 히치콕 줌 또는 현기증 효과라고 불리며

카메라의 전후로 이동하는 동시에 줌을 조절하여 독특한 원근감을 만드는 카메라 기법입니다

 

피사체의 크기는 일정하게 유지하면서 배경만 기묘하게 압축/확장해 보이는 영상 효과입니다

 

구현c++

C++에서 레벨시퀀스를 사용할려면 Build.cs파일의 수정이 필요합니다

해당 참조를 추가해줍니다

"LevelSequence", "MovieScene"

 

필요한 헤더도 추가해줍니다

#include "LevelSequence.h"
#include "LevelSequencePlayer.h"
#include "LevelSequenceActor.h"

 

BeginPlay에서 시퀀스재생준비를 하고 ActivatePortal함수를 외부에서 호출하면 시퀀스를 실행시킵니다

UPROPERTY(EditAnywhere, Category="Settings")
class ULevelSequence* portalSequence;

UPROPERTY()
class ULevelSequencePlayer* sequencePlayer;

UPROPERTY()
class ALevelSequenceActor* sequenceActor;

void APortal::BeginPlay()
{
	Super::BeginPlay();

	if (portalSequence)
	{
		FMovieSceneSequencePlaybackSettings settings;
		sequencePlayer =ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(),portalSequence,settings,sequenceActor);

		sequencePlayer->OnFinished.AddDynamic(this, &APortal::OnPortalSequenceFinished);

	}
	
}

void APortal::ActivatePortal(AMainCharacter* player)
{
	cachedPlayer = player;  

	if (!cachedPlayer)
		return;

	if (APlayerController* pc = Cast<APlayerController>(cachedPlayer->GetController()))
		pc->DisableInput(pc);

	if (sequencePlayer)
		sequencePlayer->Play();

	HidePingIndicator();
	cachedPlayer->LoadFade();

}

void APortal::OnPortalSequenceFinished()
{
	if (APlayerController* pc = Cast<APlayerController>(cachedPlayer->GetController()))
		pc->EnableInput(pc);

	cachedPlayer->LoadBossMap();
}

 

레벨 시퀀스를 만들어줍니다

 

카메라를 카메라릭에 Attach해준뒤 카메라는 카메라릭을 따라 뒤로 이동합니다

 

카메라 컴포넌트를 선택하고 이벤트 - 리피터 를 선택하여 이벤트존을 생성해줍니다

 

리피터 카메라존의 노드입니다

간단한 카메라 작업입니다 대충 플레이어와 카메라와의 거리를 계산해서 초점길이를 계산해주는일을 담당합니다

간단한작업이라 블루프린트로 진행하였습니다

 

맵 이동

맵 이동 방식은 비동기 레벨 이동 방식을 사용하였습니다

맵을 미리 로딩 후 로딩이 완료되면 맵을 이동하도록 설계하였습니다

이전글에서 다루었던 내용이니 올려두겠습니다

2026.01.20 - [Unreal 프로젝트 다이어리/두번째 프로젝트] - Unreal - 죽음 / 리스폰

 

Unreal - 죽음 / 리스폰

미리보기구현내용플레이어가 Hp가 0이 되어 죽었을때의 플레이어 죽음 처리죽음이후에 처리되는 플레이어 리스폰 처리를 구현하였습니다리스폰은 두가지 종류가 있으며플레이어의 라이프포인

lucodev.tistory.com

void ALoadGameMode::BeginPlay()
{
	Super::BeginPlay();

	gameIst = Cast<UProjectGameInstance>(GetGameInstance());
	if (gameIst && gameIst->loadingWidget)
		gameIst->loadingWidget->AddToViewport();

    FName targetMap = NAME_None;

    if (loadType == ELoadMapType::FromSave)
    {
        if (gameIst->saveManager && gameIst->saveManager->currentSave)
            targetMap = gameIst->saveManager->currentSave->savedMapName;
    }
    else if (loadType == ELoadMapType::FromFixedCoordinates)
    {
        targetMap = gameIst->loadMapToBoss;
    }



    if (!targetMap.IsNone())
    {
        FString levelPath = FString::Printf(TEXT("/Game/Maps/%s.%s"),*targetMap.ToString(),*targetMap.ToString());
        LoadPackageAsync(levelPath, FLoadPackageAsyncDelegate::CreateUObject(this, &ALoadGameMode::OnGameLevelLoaded));
    }
}

void ALoadGameMode::OnGameLevelLoaded(const FName& packageName, UPackage* loadedPackage, EAsyncLoadingResult::Type result)
{
    if (gameIst && gameIst->loadingWidget)
        gameIst->loadingWidget->SetVisibility(ESlateVisibility::Visible); 

    if (result == EAsyncLoadingResult::Succeeded)
    {
        FTimerHandle TH_OpenLevelPack;
        FTimerDelegate TD_OpenLevelDel;
        TD_OpenLevelDel.BindLambda([this, packageName]()
            {
                FString mapName = packageName.ToString();
                UGameplayStatics::OpenLevel(this, FName(*mapName));
            });

        GetWorldTimerManager().SetTimer(TH_OpenLevelPack, TD_OpenLevelDel, 3.0f, false);
    }
}

 

결과

플레이어는 포탈근처로 다가가서 상호작용 E키를 누르면 시퀀스가 발동합니다

 

 

시퀀스를 통해 달리줌 효과가 나타납니다

 

페이드아웃이 실행된뒤 로딩맵 -> 지정된 보스맵 으로 이동합니다

 

영상

(안타깝게도 3월중순부터 티스토리가 자체적으로 영상을 업로드할수없게 정책이 바뀌고

올라갔던 영상도 삭제한다더라구하더라구요 힘들지만 영상을 전부 유튜브로 옮기게 되었습니다)

https://youtu.be/6RHrnhl_qEw

 

저작자표시 비영리 변경금지 (새창열림)

'Unreal 프로젝트 다이어리 > 두번째 프로젝트' 카테고리의 다른 글

Unreal - AI (순찰, 전투)  (0) 2026.02.05
Unreal - AI (Behavior Tree 설계하기)  (0) 2026.02.02
Unreal - 상호작용 추가  (2) 2026.01.24
Unreal - 트리거 매니저 ( 낙사 & 오토세이브 )  (1) 2026.01.21
Unreal - 죽음 / 리스폰  (0) 2026.01.20
'Unreal 프로젝트 다이어리/두번째 프로젝트' 카테고리의 다른 글
  • Unreal - AI (순찰, 전투)
  • Unreal - AI (Behavior Tree 설계하기)
  • Unreal - 상호작용 추가
  • Unreal - 트리거 매니저 ( 낙사 & 오토세이브 )
lucodev
lucodev
언리얼 포폴개발 일기
  • lucodev
    루코 개발테이블
    lucodev
  • 전체
    오늘
    어제
    • 분류 전체보기 (236)
      • Unreal 프로젝트 다이어리 (132)
        • 첫번째 프로젝트 (73)
        • 두번째 프로젝트 (59)
      • Unreal 팁 (8)
      • Unreal 디버깅 (8)
      • C++ 프로그래머스 (52)
        • Stack,Queue (7)
        • Hash (4)
        • Heap (2)
        • Sort (5)
        • Exhaustive search (5)
        • Greedy (2)
        • BFS , DFS (7)
        • Graph (2)
        • Dynamic Programming (1)
        • C++ Math (2)
        • 기타 문제 (14)
      • C++ 백준 (5)
      • C++ 팁 (1)
      • 개인 코테 & 스타디 <비공개> (29)
        • 코드 개인보관함 (9)
        • 코딩테스트+@ (11)
        • 알고리즘 스타디 (6)
        • 알고리즘 스타디 과제 (3)
        • 비공개 (0)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 링크

  • 공지사항

  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 태그

    언리얼 시퀀스
    언리얼 ui
    언리얼 behavior tree
    unreal 상호작용
    언리얼 컷씬
    unreal
    언리얼
    언리얼 비헤이비어트리
    언리얼 파쿠르
    언리얼 상호작용
    unreal inventory
    unreal npc
    언리얼 세키로
    unreal 파쿠르
    언리얼 인벤토리
    unreal 세키로
    언리얼 인터렉션
    언리얼 parkour
    언리얼 behaviortree
    unreal 인벤토리
  • hELLO· Designed By정상우.v4.10.3
lucodev
Unreal - 달리 줌 (Dolly - Zoom)
상단으로

티스토리툴바