멈추지 않고 끈질기게

[Unreal] 최종 프로젝트 18일차 - 감정표현 SFX 추가 / NPC별 애니메이션 세부화 본문

포트폴리오

[Unreal] 최종 프로젝트 18일차 - 감정표현 SFX 추가 / NPC별 애니메이션 세부화

sam0308 2024. 6. 10. 18:28

※ 해당 포스팅은 개인의 공부 정리용 글입니다. 틀린 내용이 있다면 추후 수정될 수 있습니다.

※ 해당 포스팅은 청년취업사관학교 교육 과정의 최종 프로젝트에 관한 내용을 포함하고 있습니다.

 

※ 해당 포스팅은 Unreal 5.4.1 버전을 기준으로 작성되었습니다.

 

 

 

0. 서론

 이번주부터는 에셋을 적용하고 비주얼 퀄리티를 높이는 작업 위주로 진행할 예정입니다. 특히 각 NPC마다 고유한 애니메이션을 추가해주고 있는데, 해당 작업이 자연스럽게 보이게 하려니 생각보다 시간을 잡아먹을 것으로 보여 시간 배분을 잘 해야할 듯 합니다. 앞으로의 일정에 대해서 회의를 진행하였고 저는 NPC 관련 SFX, VFX 추가와 애니메이션 세부화, 그리고 메시 변경 등을 진행할 예정입니다.

 

 

1. 감정표현 SFX 추가

 NPC 대화 시 감정표현 UI(말풍선)이 나오도록 추가하였는데, 사운드 쪽 작업도 하기 시작해서 NPC의 경우 해당 UI 노출시에 SFX를 실행하도록 했습니다. 일단 일정 호감도 이상인 NPC가 플레이어를 발견했을 때 나오는 감정표현은 나머지와 성질이 조금 다르다보니 별개의 SFX를 실행하도록 했습니다.

void ANPCBase::PlayEmotion(bool IsUIOnly)
{
	if(CurEmotion.IsEmpty())
	{
		return;
	}

	EmotionUI->SetEmotion(CurEmotion);
	EmotionUI->SetVisibility(ESlateVisibility::Visible);
	if(IsUIOnly)
	{
		if(Sfx_Notice)
		{
			UGameplayStatics::PlaySound2D(GetWorld(), Sfx_Notice);
		}
	}
	else
	{
		AnimInstance->PlayMontage_Emotion(CurEmotion);
		if (Sfx_Emotion)
		{
			UGameplayStatics::PlaySound2D(GetWorld(), Sfx_Emotion);
		}
	}
}

 

 일단은 그래서 2가지로만 나누었는데, 화났을때는 불이 타는 소리 등으로 각 감정에 맞는 SFX로 세세하게 나눌 예정입니다.  

 

 

2. NPC별 애니메이션 세부화

 공통되는 애니메이션 외에 NPC별로 다른 애니메이션을 추가하는 작업을 진행했습니다. 특히 화가, 프로그래머의 경우 앉아서 작업하는 모습을 보여주기 위해 믹사모에서 앉는 애니메이션, 앉아있다 일어서는 애니메이션을 가져와서 추가하였습니다.

 

 다만 해당 작업을 추가하다보니 추가로 필요한 작업이 생겼습니다. 우선 앉아서 작업하는 NPC의 경우 플레이어와 대화 시에 갑자기 일어나서 말하면 너무 어색하다보니, 해당하는 NPC들은 작업 중에는 대화 시 애니메이션을 실행하지 않도록 수정하였습니다.

void ANPC_Programmer::StartConversation()
{
	if (ACharacter* Player = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0))
	{
		// Turn to player
		FVector DirectionVec = (Player->GetActorLocation() - GetActorLocation()).GetSafeNormal();
		DirectionVec.Z = 0;
		const FRotator TargetRot = DirectionVec.ToOrientationRotator();
		SetActorRotation(TargetRot);

		NPCController->StartConversation();
		// 일하는 중이 아닐때만 대화 애니메이션 실행
		if(false == NPCController->GetIsWorking())
		{
			AnimInstance->PlayMontage_Conv();
		}
		EmotionUI->SetVisibility(ESlateVisibility::Hidden);
	}
}

 

 그리고 앉는 모션의 경우 자연스러운 모습이 나오려면 force root lock을 해제해야 했는데, 해당 애니메이션 완료 후에 앉아서 작업하는 애니메이션을 실행하면 위치가 바뀌어 부자연스러운 모습이 노출되었습니다. 이건 일단 깔끔한 해결방법이 떠오르지 않아, 앉는 애니메이션이 종료되는 시점에 Notify를 추가하여 NPC를 바라보는 방향 반대쪽으로 일정 거리만큼 옮기는 식으로 해결하였습니다.

#include "PKH/Animation/AnimNotify_SitComplete.h"
#include "PKH/NPC/NPCBase.h"

void UAnimNotify_SitComplete::Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation)
{
	Super::Notify(MeshComp, Animation);

	ANPCBase* NPC = Cast<ANPCBase>(MeshComp->GetOwner());
	if(NPC)
	{
		const FVector SitLoc = NPC->GetActorLocation() + (NPC->GetActorForwardVector() * -50.0f);
		NPC->SetActorLocation(SitLoc);
	}
}

 

사진 1. ProgrammerWork 몽타주