KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
UGameSoundManager.cpp
이 파일의 문서화 페이지로 가기
1// Copyright (c) 2025 Doppleddiggong. All rights reserved. Unauthorized copying, modification, or distribution of this file, via any medium is strictly prohibited. Proprietary and confidential.
2
7#include "UGameSoundManager.h"
8#include "USoundData.h"
9#include "Components/AudioComponent.h"
10#include "Kismet/GameplayStatics.h"
11#include "FComponentHelper.h"
12#include "GameLogging.h"
13
14#define SOUND_DATA_PATH TEXT("/Game/CustomContents/MasterData/DA_Sound.DA_Sound")
15
17{
18 // FComponentHelper를 사용해 생성자에서 안전하게 에셋을 로드합니다.
20 {
21 for (const auto& Pair : LoadedAsset->SoundData)
22 {
23 SoundAsset = LoadedAsset;
24 SoundData = SoundAsset->SoundData;
25
26 TSoftObjectPtr<USoundBase> SoundAssetPtr = Pair.Value;
27 if (!SoundAssetPtr.IsNull()) {
28 SoundData.Add(Pair.Key, SoundAssetPtr.LoadSynchronous());
29 }
30 }
31 }
32 else
33 {
34 // 실패 시, 에디터 실행 시 Output Log에 에러를 출력합니다.
35 UE_LOG(LogTemp, Error, TEXT("UGameSoundManager failed to load USoundData at path: %s"), SOUND_DATA_PATH);
36 }
37}
38
39void UGameSoundManager::Initialize(FSubsystemCollectionBase& Collection)
40{
41 Super::Initialize(Collection);
42
43 // FSoftObjectPath AssetPath(SOUND_DATA_PATH);
44 // USoundData* LoadedAsset = Cast<USoundData>(StaticLoadObject(USoundData::StaticClass(), nullptr, *AssetPath.ToString()));
45 //
46 // if (LoadedAsset)
47 // {
48 // for (const auto& Pair : LoadedAsset->SoundData)
49 // {
50 // SoundAsset = LoadedAsset;
51 // SoundData = SoundAsset->SoundData;
52 //
53 // TSoftObjectPtr<USoundBase> SoundAssetPtr = Pair.Value;
54 // if (!SoundAssetPtr.IsNull())
55 // {
56 // SoundData.Add(Pair.Key, SoundAssetPtr.LoadSynchronous());
57 // }
58 // }
59 // }
60 // else
61 if (!SoundAsset)
62 {
63 UE_LOG(LogTemp, Error, TEXT("Failed to load SoundDataAsset from path"));
64 }
65}
66
67void UGameSoundManager::PlaySound(const EGameSoundType Type, const FVector Location)
68{
69 if (TObjectPtr<USoundBase>* FoundSound = SoundData.Find(Type))
70 {
71 if (*FoundSound)
72 {
73 UGameplayStatics::PlaySoundAtLocation(GetWorld(), *FoundSound, Location);
74 }
75 }
76}
77
78
80{
81 if (TObjectPtr<USoundBase>* FoundSound = SoundData.Find(Type))
82 {
83 if (*FoundSound)
84 {
85 // 이미 재생 중인 사운드가 있다면 멈추고 제거
86 if (UAudioComponent* ExistingComp = ActiveSounds.FindRef(Type))
87 {
88 ExistingComp->Stop();
89 ActiveSounds.Remove(Type);
90 }
91
92 // 새로운 사운드 재생 및 저장
93 if (UAudioComponent* NewComp = UGameplayStatics::SpawnSound2D(GetWorld(), *FoundSound))
94 {
95 ActiveSounds.Add(Type, NewComp);
96 }
97 }
98 }
99}
100
102{
103 if (UAudioComponent* Comp = ActiveSounds.FindRef(Type))
104 {
105 Comp->Stop();
106 ActiveSounds.Remove(Type);
107 }
108}
109
110UAudioComponent* UGameSoundManager::PlayConversationVoice(USoundBase* Sound)
111{
112 if (!Sound)
113 return nullptr;
114
115 // 기존 대화 음성이 재생 중이면 중지
117
118 // 새로운 대화 음성 재생
119 ConversationVoice = UGameplayStatics::SpawnSound2D(GetWorld(), Sound);
120 return ConversationVoice;
121}
122
124{
125 if (ConversationVoice && ConversationVoice->IsPlaying())
126 {
127 ConversationVoice->Stop();
128 }
129 ConversationVoice = nullptr;
130}
131
136
138{
139 // 이미 같은 BGM 타입이고, AudioComponent가 유효하며 재생 중인지 확인
140 // (레벨 전환 시 AudioComponent가 파괴되므로 IsValid 체크 필수)
141 if ( CurrentBGMType == Type &&
142 IsValid(CurrentBGM)
143 && CurrentBGM->IsPlaying())
144 {
145 return;
146 }
147
148 // 기존 BGM 중지
149 StopBGM();
150
151 // 새 BGM 재생
152 if (TObjectPtr<USoundBase>* FoundSound = SoundData.Find(Type))
153 {
154 if (*FoundSound)
155 {
156 // bPersistAcrossLevelTransition = true로 설정하여 레벨 전환에도 유지되도록 함
157 CurrentBGM = UGameplayStatics::CreateSound2D(
158 GetWorld(),
159 *FoundSound,
160 1.0f, // VolumeMultiplier
161 1.0f, // PitchMultiplier
162 0.0f, // StartTime
163 nullptr, // ConcurrencySettings
164 true, // bPersistAcrossLevelTransition - 레벨 전환에도 유지
165 false // bAutoDestroy
166 );
167
168 if (CurrentBGM)
169 {
170 CurrentBGM->Play();
171 CurrentBGMType = Type;
172 }
173 }
174 }
175}
176
178{
179 if (IsValid(CurrentBGM) && CurrentBGM->IsPlaying())
180 {
181 CurrentBGM->Stop();
182 }
183 CurrentBGM = nullptr;
184}
EGameSoundType
FComponentHelper 구조체를 선언합니다.
YiSan 전반에서 사용하는 공용 인터페이스를 선언합니다.
#define SOUND_DATA_PATH
UGameSoundManager 클래스를 선언합니다.
USoundData 클래스를 선언합니다.
TMap< EGameSoundType, UAudioComponent * > ActiveSounds
TMap< EGameSoundType, TObjectPtr< class USoundBase > > SoundData
void StopSound2D(const EGameSoundType Type)
virtual void Initialize(FSubsystemCollectionBase &Collection) override
void PlayBGM(EGameSoundType Type)
BGM을 재생합니다.
void PlaySound(EGameSoundType Type, FVector Location)
TObjectPtr< class USoundData > SoundAsset
UAudioComponent * PlayConversationVoice(USoundBase *Sound)
void StopBGM()
현재 재생 중인 BGM을 중지합니다.
TObjectPtr< UAudioComponent > CurrentBGM
void PlaySound2D(EGameSoundType Type)
bool IsConversationVoicePlaying() const
TObjectPtr< UAudioComponent > ConversationVoice
EGameSoundType CurrentBGMType
static T * LoadAsset(const TCHAR *Path)