[Unreal_C++_DarkSoul]#18_기능 구현, Sound

2023. 7. 23. 12:53· 개인프로젝트
목차
  1.  
  2. [Unreal_C++_DarkSoul]#18_Sound

 

[Unreal_C++_DarkSoul]#18_Sound

 

Sound를 구현합니다.

 


 

Overview

 

  1. 개요 및 설계
  2. 코드
  3. 영상

 

#1. 개요 및 설계

1. 개요

 

[디자인 패턴]#13_이벤트 큐, Event Queue

[디자인 패턴] #13_이벤트 큐, Event Queue 게임 디자인 패턴 중 "디커플링 패턴"에 대해 알아보겠습니다. "게임 프로그래밍 패턴"의 15 항목, "이벤트 큐"에 해당하는 내용입니다. 의도 이벤트를 보내

webddevys.tistory.com

 

  • 게임 플레이에 필요한 사운드 이펙트들을 재생하기 위해  Sound 클래스를 구현합니다.
  • Sound 객체는 월드 어느 곳에서도 배경 음악을 재생합니다.
  • Sound 객체는 캐릭터의 자연스러운 행동 연출을 위한 사운드 이펙트를 재생합니다.
  • Event Queue 디자인 패턴을 적용해 사운드 재생 요청과 처리 시점을 디커플링 합니다. 이러한 비동기 처리를 통해 다음 이벤트 처리가 블로킹되어 시스템 성능에 영향을 끼치는 것을 방지하고, 이벤트 처리 순서를 더 안정적으로 관리할 수 있으며, Sound 객체와 여타 사운드 재생 요청을 보내는 객체들 간의 커플링을 감소시킵니다. 

 

2. 설계

  1. 먼저, Sound 클래스를 정의합니다. Sound 클래스는 다른 객체로 부터 전달받은 SoundCue 형식의 데이터를 Sound Event Queue에 차례대로 삽입합니다.
  2. 다음으로, Sound 클래스를 상속하는 BGSound 클래스를 정의합니다. BGSound 클래스는 현재 재생하고 있는 배경 음악 재생 시간이 끝나면 Event Queue의 마지막 위치에 다시 삽입합니다. 그리고, 다음 배경 음악을 자동적으로 재생합니다.
  3. 마지막으로, Sound 클래스를 상속하는 EffectSound 클래스를 정의합니다. Effect 클래스는 World 내 다른 객체들로 부터 SoundCue 형식의 데이터를 전달받아 Event Queue에 차례대로 삽입하고 가장 먼저 들어온 SoundCue부터  차례대로 재생합니다.  

 

#1. 코드

1. Sound 클래스

#include "Sound.h"
#include "Global/Global.h"

ASound::ASound()
{

	PrimaryActorTick.bCanEverTick = true;

}

void ASound::BeginPlay()
{

	Super::BeginPlay();

}

void ASound::Tick(float DeltaTime)
{

	Super::Tick(DeltaTime);

}


void ASound::PlaySoundAtLocation(USoundCue* InSoundCue, const AActor* InActor)
{

	if (!!InSoundCue && !!InActor)
	{
		UGameplayStatics::PlaySoundAtLocation(
			InActor->GetWorld(),
			InSoundCue,
			InActor->GetActorLocation()
		);
	}

}


// [23-06-30] Sound Event Queue
/*	************************************************************************

	목적:
		Human Sound와 Weapon Sound를 Audio Component로 부터 받아와 재생합니다.
	설명:
		InSoundCue1 = Human Sound
		InSoundCue2 = Weapon Sound

*	************************************************************************/

void ASound::AddNewSoundCueToEventQueue(USoundCue* InSoundCue1, USoundCue* InSoundCue2,
	const AActor* InActor1, const AActor* InActor2)
{

	if (!!InSoundCue1 && !!InActor1)
	{
		QSoundEvents.Enqueue(MakeTuple(InSoundCue1, InActor1));
	}

	if (!!InSoundCue2 && !!InActor2)
	{
		QSoundEvents.Enqueue(MakeTuple(InSoundCue2, InActor2));
	}

}

 

Details

 

  1. SoundCue 형식의 데이터가 특정 위치에서 재생되는 사운드일 경우 PlaySoundAtLocation를 호출합니다.
  2. 새로운 SoundCue를 전달 받았을 경우 AddNewSoundCueToEventQueue() 함수를 호출해 Event Queue의 마지막 위치에 해당 SoundCue를 삽입합니다.

 

2. BackgroundSound 클래스

#include "BackgroundSound.h"
#include "Global/Global.h"

#include "Components/AudioComponent.h"

ABackgroundSound::ABackgroundSound()
{}

void ABackgroundSound::BeginPlay()
{

	Super::BeginPlay();

	// #1. BG Sounds
	if (SoundCues.Num() > 0)
	{
		for (const auto& SoundCue : SoundCues)
		{
			QBGSoundCues.Enqueue(SoundCue);
		}
	}

	SpawnBGSoundCue();

}


void ABackgroundSound::SpawnBGSoundCue()
{

	if (QBGSoundCues.IsEmpty() == false)
	{
		BGAudioComp = UGameplayStatics::SpawnSound2D(GetWorld(), *(QBGSoundCues.Peek()));
		if (!!BGAudioComp)
		{
			BGAudioComp->OnAudioFinished.AddDynamic(this, &ABackgroundSound::OnBGSoundFinished);
			BGAudioComp->bAutoDestroy = false;
		}
		else
		{
			PrintLine();
		}
	}

}

void ABackgroundSound::OnBGSoundFinished()
{

	if (BGAudioComp != nullptr)
	{
		BGAudioComp->Stop();
		USoundCue* PrevSoundCue;
		if (QBGSoundCues.Dequeue(PrevSoundCue) && !QBGSoundCues.IsEmpty())
		{
			SpawnBGSoundCue();
			QBGSoundCues.Enqueue(PrevSoundCue);
		}
	}

}

 

Details

 

  1. BackgroundSound 클래스는 게임 플레이 시작 전에 미리 설정한 배경 음악들을 게임 시작과 함께 Event Queue에 삽입합니다.
  2. UGameplayStatics가 제공하는 SpawnSound2D()를 통해 World에 배경 음악 SoundCue를 Spawn 합니다. 
  3. 현재 재생되고 있는 배경 음악이 끝날 경우, OnBGSoundFinished() 함수를 호출해서 해당 배경 음악의 재생을 정지하고, Event Queue의 다음 배경음악을 재생합니다. 

 

3. EffectSound 클래스

#include "EffectSound.h"
#include "Global/Global.h"

#include "GameObjects/GameObject.h"
#include "ActorComponents/C_AudioComponent.h"

AEffectSound::AEffectSound()
{
}

void AEffectSound::BeginPlay()
{

	Super::BeginPlay();

	// [23-06-20] Event Queue
	TArray<AActor*> Objects;
	UGameplayStatics::GetAllActorsOfClass(GetWorld(), AGameObject::StaticClass(), Objects);
	for (const auto& Object : Objects)
	{
		if (!!Object)
		{
			UC_AudioComponent* AudioComponent = Object->FindComponentByClass<UC_AudioComponent>();
			if (!!AudioComponent)
			{
				AudioComponent->OnSendEffectSound.BindUFunction(this, "AddNewSoundCueToEventQueue");
			}
		}
	}

}

void AEffectSound::Tick(float DeltaTime)
{

	Super::Tick(DeltaTime);

	// [23-06-30] Sound Event Queue
	if (!QSoundEvents.IsEmpty())
	{
		PlaySoundAtLocation(QSoundEvents.Peek()->Get<0>(), QSoundEvents.Peek()->Get<1>());
		QSoundEvents.Pop();
	}

}

 

Details

 

  1. 월드 내 GameObject 형식의 객체들을 가져와서 이들이 갖는 Audio Comopnent가 선언한 OnSendEffectSound 델리게이트 함수와 AddNewSoundCueToEventQueue 함수를 동적 바인딩 합니다.
  2. Tick() 함수는 매 프레임마다 호출되는 함수로 Event Queue에 저장된 SoundCue 형식의 데이터를 차례대로 재생합니다.

 

#2. 영상

 

 

 

 

'개인프로젝트' 카테고리의 다른 글

[Unreal_C++_DarkSoul]#20_기능 구현, Level Sequence  (0) 2023.09.17
[Unreal_C++_DarkSoul]#19_기능 구현, Portal  (0) 2023.07.23
[Unreal_C++_DarkSoul]#17_기능 구현, Grid 클래스  (0) 2023.06.03
[Unreal_C++_DarkSoul]#16_문제 해결, 런 타임 AI 실행 여부  (0) 2023.05.27
[Unreal_C++_DarkSoul]#15_문제 해결, Data Table 로드 함수  (1) 2023.05.08
  1.  
  2. [Unreal_C++_DarkSoul]#18_Sound
'개인프로젝트' 카테고리의 다른 글
  • [Unreal_C++_DarkSoul]#20_기능 구현, Level Sequence
  • [Unreal_C++_DarkSoul]#19_기능 구현, Portal
  • [Unreal_C++_DarkSoul]#17_기능 구현, Grid 클래스
  • [Unreal_C++_DarkSoul]#16_문제 해결, 런 타임 AI 실행 여부
Hardii2
Hardii2
개발 블로그Hardii2 님의 블로그입니다.
Hardii2
개발 블로그
Hardii2
전체
오늘
어제
  • 분류 전체보기
    • 알고리즘
    • 웹 개발
      • Node.js
      • React
    • 게임개발
      • DirectX12
      • 관련 지식
      • Unreal C++
      • Unreal 블루프린트
    • 언어
      • Effective C++
      • Basic C++
      • 디자인 패턴
      • 자료구조
      • 기술 질문
    • 문제 풀이
      • BOJ 문제 풀이
      • Programmers 문제 풀이
      • geeksForgeeks 문제 풀이
    • 수학
      • 확률과 통계
      • 게임수학
    • 개인프로젝트
    • 그룹프로젝트
      • PM
      • Dev
    • Github

블로그 메뉴

  • 홈
  • 글쓰기

공지사항

인기 글

태그

  • unreal
  • DP
  • 개발
  • set
  • BFS
  • programmers
  • 트리
  • 기술 질문
  • 우선순위 큐
  • 정렬
  • Unreal Blueprint
  • C++
  • 디자인 패턴
  • 알고리즘
  • 최단 경로
  • Effective C++
  • BOJ
  • stl
  • dfs
  • 그래프

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
Hardii2
[Unreal_C++_DarkSoul]#18_기능 구현, Sound
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.