Unrela - 시퀀스 만들기 (캐릭터편)

2025. 5. 21. 20:23·Unreal5 프로젝트 다이어리

첫 던전을 입장할때 캐릭터 옆부터 앞을 비추다가 다시 원래시점으로 돌아가는 연출을 내고싶었습니다

시퀀스를 사용해보겠습니다

시네 카메라를 설치합니다

 

설치된 시네카메라를 클릭후 파일럿버튼을 누르면 카메라 시점으로 움직이게 설정할수있습니다

좌측 상단의 화살표 모양을 누르면 다시 돌아갈수있습니다

 

필름백에서 카메라의 종류를 선택할수있습니다

잘모르겠다면 DSLR 또는 디지털필름을 사용해주세요

 

크롭세팅입니다

화면을 비율에 맞춰 잘라줍니다

화면비가 대부분 16:9이니 1.77으로 설정

 

초점거리가 낮을수록 넓게볼수 있습니다

 

원하는 위치에 시네카메라를 만든뒤 배치합니다

 

시퀀스를 추가후 저장해줍니다

 

레벨 시퀀스를 추가하면 프레임을 설정해줍니다

 

사용하고있는 시네카메라를 드래그앤드랍을 해서 카메라를 추가합니다

 

위치를 잡아주시고 키를 찍어준뒤

카메라의 중점에 잡고싶은 대상을 트랙할 액터 스포이드로 찍어주신뒤 룩앳트래킹 활성화를

눌러주시게 되면 해당 액터를 중점으로 카메라가 이동합니다

 

여기서 만약 다른카메라로 이동하여 다른카메라로 찍고 그 카메라를 연결할려면

카메라를 하나 더 추가한뒤 트랜스폼값 키를 찍어줍니다

 

두개의 카메라를 연결시켜줘야합니다

카메라컷을 활성화해줍니다

 

두번째카메라를 연동시켜줍니다

 

c++에서 만든 시퀀스를 재생하기위해서는 Build.Cs에 모듈을 추가해야합니다 해당 모듈을 추가해줍니다

"MovieScene", "MovieSceneTracks", "LevelSequence"

 

필요한 헤더를 추가합니다

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

 

블루프린트에서 할당해줄 시퀀스를 참조할 ULevelSequence를 만듭니다

UPROPERTY(EditAnywhere, Category = "Sequence")
class ULevelSequence* characterSwordSequence;

 

세팅을 하고 시퀀스를 플레이시킵니다

FMovieSceneSequencePlaybackSettings playSetting;
ALevelSequenceActor* sequenceActor = nullptr;
playSetting.bAutoPlay = false;
ULevelSequencePlayer* swordSequensePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(),characterSwordSequence, playSetting, sequenceActor);
swordSequensePlayer->Play();

 

컷씬이 나올동안은 플레이어의 input이 들어가면 안됩니다

컨트롤러의 모든 input을 막아주도록 하겠습니다

현재 작성하고있는곳은 GameMode의 BeginPlay이기때문에 플레이어 BeinPlay보다 더 빨리 작동하니깐

타이머를 작성하여 0.1초뒤에 모든 인풋을 막도록 하겠습니다

 

해당코드는 DisableInput으로 사용하고있는 컨트롤러의 입력을 제한합니다

ASwordPlayController* swordController = Cast<ASwordPlayController>(GetWorld()->GetFirstPlayerController());
FTimerHandle th_stopInputComponent;
GetWorld()->GetTimerManager().SetTimer(th_stopInputComponent, [swordController]()
	{
		if (swordController && swordController->InputComponent)
		{
			swordController->DisableInput(swordController);
		}
	}, 0.1f, false);

 

컷씬이 끝나면 다시 인풋을 받을수있는함수를 만듭니다

EnableInput으로 다시 컨트롤러의 인풋을 받습니다

//다시 활성화해줄 함수
void ASwordPlayerGameBase::SwordSequenceFinish()
{
	ASwordPlayController* swordController = Cast<ASwordPlayController>(GetWorld()->GetFirstPlayerController());
	swordController->EnableInput(swordController);
}

 

 

델리게이트로 해당함수와 연결하여 시퀀스가 끝나면 해당 함수를 콜백합니다

swordSequensePlayer->OnFinished.AddDynamic(this, &ASwordPlayerGameBase::SwordSequenceFinish);

 

시퀀스가 나올때는 UI가 보이면 안됩니다 UI도 가려주겠습니다

플레이어가 BeginPlay할때 UI를 뷰포트에 띄웁니다

 

플레이어의 BeginPlay에 뷰포트에 띄울때 조건을 추가합니다

(gameMode->bUseCharactersequence == false)

APlayerController* playerController = Cast<APlayerController>(GetController());
if (playerController)
{
	characterWidget = CreateWidget<USwordCharacterWidget>(playerController, LoadClass<USwordCharacterWidget>(nullptr, TEXT("/Game/Luco/UI/SwordCharacterWidget.SwordCharacterWidget_C")));

	if (characterWidget && gameMode->bUseCharactersequence == false)
	{
		characterWidget->AddToViewport();

 

이렇게되면 gameMode의 bUseCharactersequence가 false면 생성하지않습니다

그러면 시퀀스가 끝난뒤 따로 위젯을 만든뒤 띄워주겠습니다

 

게임모드에서 해당 코드를 작성합니다

해당코드는 페이드인을 해주는코드입니다

중간에 PlayCharacterSwordSequence로 시퀀스를 실행시킵니다

if (bUseCharactersequence)
{
	fadeWidgetInstance = CreateWidget<UFadeInOutWidget>(pCon, fadeWidget);
	if (fadeWidgetInstance)
	{
		fadeWidgetInstance->AddToViewport();
		PlayCharacterSwordSequence();
		if (fadeWidgetInstance->FadeIn)
		{
			FWidgetAnimationDynamicEvent endEventD1;
			endEventD1.BindDynamic(this, &ASwordPlayerGameBase::OnFadeInFinishedCharacterUISetting);
			fadeWidgetInstance->BindToAnimationFinished(fadeWidgetInstance->FadeIn, endEventD1);

		}
	}
	fadeWidgetInstance->PlayFadeIn();
}

 

PlayCharacterSwordSequence의 코드입니다

모드를 바꾸고 인풋을 막고 애니메이션을 실행하며 

"swordSequensePlayer->OnFinished.AddDynamic(this, &ASwordPlayerGameBase::SwordSequenceFinish);" 쪽에서

시퀀서가 끝나면 SwordSequenceFinish함수를 호출합니다

void ASwordPlayerGameBase::PlayCharacterSwordSequence()
{
	ASwordPlayController* swordController = Cast<ASwordPlayController>(GetWorld()->GetFirstPlayerController());
	TWeakObjectPtr<ASwordCharacter> capturePlayer = Cast<ASwordCharacter>(pCon->GetPawn());
	FTimerHandle th_PlayerAttackMode;
	FTimerHandle th_PlayerPlaySwitchSwordAnim;
	FTimerHandle th_PlayerSwordHidden;
	FTimerHandle th_stopInputComponent;

	//stopPlayer
	if (InputComponent && InputComponent->IsActive())
	{
		InputComponent->Deactivate();
	}
	//tabMode -> swordVisible False -> animinstance to visible -> animation
	GetWorld()->GetTimerManager().SetTimer(th_stopInputComponent, [swordController]()
		{
			if (swordController && swordController->InputComponent)
			{
				swordController->DisableInput(swordController);
			}
		}, 0.01f, false);
	GetWorld()->GetTimerManager().SetTimer(th_PlayerAttackMode, [swordController]() {swordController->InputTab();
		}, 0.1f, false);
	GetWorld()->GetTimerManager().SetTimer(th_PlayerSwordHidden, [capturePlayer]() {capturePlayer->overlapSword->SetVisibility(false);
		}, 0.1f, false);
	GetWorld()->GetTimerManager().SetTimer(th_PlayerPlaySwitchSwordAnim, [capturePlayer]() {capturePlayer->playSwitchAnim();
		}, 0.11f, false);

	FMovieSceneSequencePlaybackSettings playSetting;
	ALevelSequenceActor* sequenceActor = nullptr;
	playSetting.bAutoPlay = false;
	ULevelSequencePlayer* swordSequensePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), characterSwordSequence, playSetting, sequenceActor);
	swordSequensePlayer->Play();
	//can move player call delegate
	swordSequensePlayer->OnFinished.AddDynamic(this, &ASwordPlayerGameBase::SwordSequenceFinish);
}

 

SwordSequenceFinish함수입니다

해당함수에서는 뷰포트에 플레이어ui를 별도로 띄우게됩니다

void ASwordPlayerGameBase::SwordSequenceFinish()
{
	ASwordPlayController* swordController = Cast<ASwordPlayController>(GetWorld()->GetFirstPlayerController());
	USwordCharacterWidget* playerMainUI = Cast<USwordCharacterWidget>(swordController->swordCharacterWidget);
	swordController->EnableInput(swordController);
	if (swordController)
	{
		characterWidget = CreateWidget<USwordCharacterWidget>(swordController, characterWidgetAsset);
		characterWidget->AddToViewport();
	}
}
UPROPERTY(EditAnywhere, Category = "SequenceAfter")
TSubclassOf<USwordCharacterWidget> characterWidgetAsset;

UPROPERTY(EditAnywhere, Category = "Sequence")
class USwordCharacterWidget* characterWidget;

++ 블루프린트에서 할당 꼭 해줍니다

 

'Unreal5 프로젝트 다이어리' 카테고리의 다른 글

Unrela - 시퀀스 만들기 (AI편)  (0) 2025.05.22
Unreal - 부숴지는 벽 만들기 (Chaos Distruction)  (0) 2025.05.22
Unreal - 레벨이동시 게임저장, 로드하기 (Save Game)  (1) 2025.05.20
Unreal - 몬스터 웨이브 만들기  (0) 2025.05.17
Unreal - 버튼 위젯 사용하기  (0) 2025.05.16
'Unreal5 프로젝트 다이어리' 카테고리의 다른 글
  • Unrela - 시퀀스 만들기 (AI편)
  • Unreal - 부숴지는 벽 만들기 (Chaos Distruction)
  • Unreal - 레벨이동시 게임저장, 로드하기 (Save Game)
  • Unreal - 몬스터 웨이브 만들기
lucodev
lucodev
커피와 노트북 그리고 개발
  • lucodev
    루코 개발테이블
    lucodev
  • 전체
    오늘
    어제
    • 분류 전체보기 (119) N
      • Unreal5 프로젝트 다이어리 (73)
      • Unreal5 프로젝트 다이어리2 (2)
      • Unreal 팁 (8)
      • Unreal 디버깅 (8)
      • C++ 프로그래머스 다이어리 (21) N
        • Stack (3)
        • Hash (4)
        • Heap (2)
        • Sort (1) N
      • 코드 개인보관함 (7)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 링크

  • 공지사항

  • 블로그 메뉴

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

    언리얼 foot step
    unreal 로딩
    언리얼 look at
    언리얼 로딩창
    unreal 컷씬
    unreal look at
    언리얼 로딩
    언리얼 spawn
    unreal sequence
    언리얼 behavior tree
    언리얼 시퀀스
    언리얼
    unreal 시퀀스
    언리얼 컷씬
    언리얼 behaviortree
    언리얼 페이드 인
    언리얼 스폰
    unreal loading
    언리얼 비헤이비어트리
    언리얼 페이드 아웃
  • hELLO· Designed By정상우.v4.10.3
lucodev
Unrela - 시퀀스 만들기 (캐릭터편)
상단으로

티스토리툴바