KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
UPopup_ReadQuest.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
3#include "UPopup_ReadQuest.h"
4#include "ALingoGameState.h"
5#include "ALingoPlayerState.h"
6#include "APlayerActor.h"
7#include "UBroadcastManager.h"
8#include "UImageButton.h"
10#include "ULingoGameHelper.h"
11#include "UPopupManager.h"
12#include "UPopup_Word.h"
13#include "UWordWidget.h"
14#include "Components/RichTextBlock.h"
15#include "HyperLinkPluginBPLibrary.h"
16#include "UWordItem.h"
17#include "Components/HorizontalBox.h"
18#include "Components/Spacer.h"
19#include "GameFramework/PlayerController.h"
20
22{
23 Super::NativeConstruct();
24
25 // URichText 기능 이식: HyperLink 클릭 핸들러 등록
26 if (Rich_Text)
27 {
28 if (UHyperLinkPluginBPLibrary* LinkDecorator = Cast<UHyperLinkPluginBPLibrary>(
29 Rich_Text->GetDecoratorByClass(UHyperLinkPluginBPLibrary::StaticClass())))
30 {
31 LinkDecorator->SetNativeClickHandler(FOnClickLink::CreateUObject(this, &UPopup_ReadQuest::OnClickHyperlink));
32 }
33 }
34}
35
37{
38 if (Btn_Confirm)
39 {
40 Btn_Confirm->OnButtonClickedEvent.RemoveDynamic(this, &UPopup_ReadQuest::OnClickClose);
41 Btn_Confirm->OnButtonClickedEvent.AddDynamic(this, &UPopup_ReadQuest::OnClickClose);
42 }
43
44 if (auto BM = UBroadcastManager::Get(GetWorld()))
45 {
46 BM->OnUpdateQuestRole.RemoveDynamic(this, &UPopup_ReadQuest::InitQuestInfo);
47 BM->OnUpdateQuestRole.AddDynamic(this, &UPopup_ReadQuest::InitQuestInfo);
48 }
49
51 this->ReadData = InScenarioData;
52
53 if ( const auto PS= ULingoGameHelper::GetLingoPlayerState(GetWorld()) )
54 InitQuestInfo(PS->QuestRole);
55}
56
58{
60
61 FString TextString;
62 for (int32 i = 0; i < CachedPhonemeData.Num(); ++i)
63 {
64 const FPhonemeData& Phoneme = CachedPhonemeData[i];
65 TextString += Phoneme.ToRichTextString(i);
66 }
67 return TextString;
68};
69
71{
73 {
74 if ( QuestRole == EQuestRole::Both )
75 {
76 const FString RichTextString = ConvertWordDataToRichText(ReadData.full_data);
77
78 Rich_Text->SetText(FText::FromString(RichTextString));
79 Txt_SubTitle->SetText(FText::FromString(ReadData.full_data.Eng));
80 }
81 else if ( QuestRole == EQuestRole::OnlyQuestion1 )
82 {
83 const FString RichTextString = ConvertWordDataToRichText(ReadData.word_data1);
84
85 Rich_Text->SetText(FText::FromString(RichTextString));
86 Txt_SubTitle->SetText(FText::FromString(ReadData.word_data1.Eng));
87 }
88 else if ( QuestRole == EQuestRole::OnlyQuestion2 )
89 {
90 const FString RichTextString = ConvertWordDataToRichText(ReadData.word_data2);
91
92 Rich_Text->SetText(FText::FromString(RichTextString));
93 Txt_SubTitle->SetText(FText::FromString(ReadData.word_data2.Eng));
94 }
95 }
96
97 InitWordList(QuestRole);
98}
99
101{
102 WordBox->ClearChildren();
103
104 if (WordItemClass == nullptr)
105 return;
106
107 auto AnswerData = ReadData.GetCorrectAnswerData();
108
109 if ( QuestRole == EQuestRole::Both )
110 {
111 if ( auto WordItem = CreateWidget<UWordItem>(this, WordItemClass) )
112 {
113 EWordType WordType = EWordType::Animal;
114 const int32 WordCode = FCString::Atoi(*AnswerData.word1.code);
115 WordItem->InitInfo(WordType, WordCode);
116
117 WordBox->AddChild(WordItem);
118 }
119
120 {
121 USpacer* Spacer = NewObject<USpacer>(WordBox);
122 Spacer->SetSize(FVector2D(10.f, 1.f));
123 WordBox->AddChild(Spacer);
124 }
125
126 if ( auto WordItem = CreateWidget<UWordItem>(this, WordItemClass) )
127 {
128 EWordType WordType = EWordType::Color;
129 const int32 WordCode = FCString::Atoi(*AnswerData.word2.code);
130 WordItem->InitInfo(WordType, WordCode);
131
132 WordBox->AddChild(WordItem);
133 }
134 }
135 else if ( QuestRole == EQuestRole::OnlyQuestion1 )
136 {
137 if ( auto WordItem = CreateWidget<UWordItem>(this, WordItemClass) )
138 {
139 EWordType WordType = EWordType::Animal;
140 const int32 WordCode = FCString::Atoi(*AnswerData.word1.code);
141 WordItem->InitInfo(WordType, WordCode);
142
143 WordBox->AddChild(WordItem);
144 }
145 }
146 else if ( QuestRole == EQuestRole::OnlyQuestion2 )
147 {
148 if ( auto WordItem = CreateWidget<UWordItem>(this, WordItemClass) )
149 {
150 EWordType WordType = EWordType::Color;
151 const int32 WordCode = FCString::Atoi(*AnswerData.word2.code);
152 WordItem->InitInfo(WordType, WordCode);
153
154 WordBox->AddChild(WordItem);
155 }
156 }
157}
158
159
161{
162 if (UPopupManager* PopupMgr = UPopupManager::Get(GetWorld()))
163 {
164 PopupMgr->HideCurrentPopup();
165 }
166}
167
168void UPopup_ReadQuest::RequestListenAudio(const FString& AudioText)
169{
170 if (bIsRequest)
171 return;
172
173 if (auto KLingoNetwork = UKLingoNetworkSystem::Get(GetWorld()))
174 {
175 bIsRequest = true;
176
177 KLingoNetwork->RequestListenAudio(
178 AudioText,
179 FResponseListenAudioDelegate::CreateUObject(this, &UPopup_ReadQuest::OnResponseListenAudio)
180 );
181 }
182}
183
184void UPopup_ReadQuest::OnResponseListenAudio(FResponseListenAudio& ResponseData, bool bWasSuccessful)
185{
186 bIsRequest = false;
187
188 if (bWasSuccessful)
189 {
190 if (auto PlayerActor = ULingoGameHelper::GetPlayerActor(this))
191 PlayerActor->PlayTTSAudio(ResponseData.audio_base64);
192 }
193}
194
195void UPopup_ReadQuest::OnClickHyperlink(const FString& LinkID, const FString& Content)
196{
197 // URichText 기능 이식: LinkID를 인덱스로 변환하여 캐싱된 음소 데이터 가져오기
198 const int32 Index = FCString::Atoi(*LinkID);
199
200 if (CachedPhonemeData.IsValidIndex(Index))
201 {
202 if (auto Popup = UPopupManager::ShowPopupAs<UPopup_Word>(GetWorld(), EPopupType::Word))
203 {
204 Popup->InitPopup(CachedPhonemeData[Index]);
205 }
206 }
207}
Declares the player-controlled character actor.
EQuestRole
Read 퀘스트에서 플레이어의 역할을 정의합니다.
Definition EQuestRole.h:6
EWordType
Definition EWordType.h:9
KLingo API 요청을 담당하는 서브시스템을 선언합니다.
static class ALingoPlayerState * GetLingoPlayerState(const UObject *WorldContextObject)
static class APlayerActor * GetPlayerActor(const UObject *WorldContextObject)
첫 번째 플레이어의 PlayerActor를 가져옵니다.
팝업 관리자
void InitQuestInfo(EQuestRole QuestRole)
TObjectPtr< class UImageButton > Btn_Confirm
TSubclassOf< class UWordItem > WordItemClass
void InitRead(const FResponseReadScenario &InScenarioData)
void OnClickHyperlink(const FString &LinkID, const FString &Content)
TObjectPtr< class URichTextBlock > Rich_Text
void InitWordList(EQuestRole QuestRole)
TArray< FPhonemeData > CachedPhonemeData
TObjectPtr< class UTextBlock > Txt_SubTitle
FString ConvertWordDataToRichText(const FWordData &WordData)
void RequestListenAudio(const FString &AudioText)
FResponseReadScenario ReadData
virtual void NativeConstruct() override
void OnResponseListenAudio(FResponseListenAudio &ResponseData, bool bWasSuccessful)
TObjectPtr< class UHorizontalBox > WordBox
단어 데이터 구조체입니다.
FString ToRichTextString(int32 Index) const
TArray< uint8 > audio_base64
FScenarioTargetData GetCorrectAnswerData() const
단어 데이터 구조체입니다.
TArray< FPhonemeData > GetPhonemeData() const
FString Eng