KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
QuestionnaireKiosk.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
5
6#include "GameLogging.h"
7#include "UInteractWidget.h"
11#include "UPopupManager.h"
12#include "UPopup_MsgBox.h"
13#include "Components/BoxComponent.h"
14#include "Components/WidgetComponent.h"
15#include "ALingoGameState.h"
16#include "ALingoPlayerState.h"
17#include "APlayerActor.h"
18#include "APlayerControl.h"
19#include "Kismet/GameplayStatics.h"
20#include "Kismet/KismetMathLibrary.h"
21
22#define INTERACT_WIDGET_PATH TEXT("/Game/CustomContents/UI/Widgets/WBP_InteractWidget.WBP_InteractWidget_C")
23
24class UInteractWidget;
25// Sets default values
27{
28 // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
29 PrimaryActorTick.bCanEverTick = true;
30
31 RootSceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("RootSceneComp"));
32 SetRootComponent(RootSceneComp);
33
34 KioskMeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("KioskMeshComp"));
35 KioskMeshComp->SetupAttachment(RootComponent);
36
37 WidgetGuideComp = CreateDefaultSubobject<UWidgetComponent>(TEXT("WidgetGuideComp"));
38 WidgetGuideComp->SetupAttachment(RootComponent);
39 WidgetGuideComp->SetRelativeLocationAndRotation(FVector(0, 0, 220), FRotator(0, 90, 0));
40 WidgetGuideComp->SetDrawAtDesiredSize(true);
41 ConstructorHelpers::FClassFinder<UUserWidget> widgetGuideRef(TEXT("/Game/CustomContents/UI/Widgets/WBP_QuestionnaireKioskGuideWidget.WBP_QuestionnaireKioskGuideWidget_C"));
42 if (widgetGuideRef.Succeeded())
43 {
44 WidgetGuideComp->SetWidgetClass(widgetGuideRef.Class);
45 }
46
47 InteractableComp = CreateDefaultSubobject<UInteractableComponent>(TEXT("InteractableComp"));
48 InteractableComp->InteractionType = EInteractionType::Kiosk;
49 InteractableComp->InteractionPrompt = TEXT("Activate");
50
51 BoxComp = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComp"));
52 BoxComp->SetupAttachment(GetRootComponent());
53 BoxComp->SetRelativeLocation(FVector(0, 36, 75));
54 BoxComp->SetBoxExtent(FVector(60, 65, 92));
55
56 WidgetComp = CreateDefaultSubobject<UWidgetComponent>(TEXT("WidgetComp"));
57 ConstructorHelpers::FClassFinder<UInteractWidget> WidgetRef(INTERACT_WIDGET_PATH);
58 if (WidgetRef.Succeeded())
59 {
60 WidgetComp->SetWidgetClass(WidgetRef.Class);
61 WidgetComp->SetupAttachment(GetRootComponent());
62 WidgetComp->SetWidgetSpace(EWidgetSpace::Screen);
63 WidgetComp->SetDrawSize(FVector2D(2048.0f, 1024.0f));
64 }
65
67}
68
70{
71 Super::BeginPlay();
72
73 // 델리게이트 바인딩
74 InteractableComp->InitWidget(WidgetComp);
75 InteractableComp->OnInteractionTriggered.AddDynamic(this, &AQuestionnaireKiosk::OnInteractionTriggered);
76 InteractableComp->OnOutlineStateChanged.AddDynamic(this, &AQuestionnaireKiosk::OnOutlineStateChanged);
77}
78
79void AQuestionnaireKiosk::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
80{
81 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
82}
83
84void AQuestionnaireKiosk::Tick(float DeltaTime)
85{
86 Super::Tick(DeltaTime);
87
89}
90
92{
93 if (APlayerActor* player = Cast<APlayerActor>(Interactor))
94 {
95 if (APlayerControl* pc = Cast<APlayerControl>(player->GetController()))
96 {
97
98 }
99 }
100
101 if (auto KLingoNetwork = UKLingoNetworkSystem::Get(GetWorld()))
102 {
103 // QuestionnaireData에 데이터가 있다면
105 {
106 PRINTLOG(TEXT("QuestionnaireData is valid"));
107 ShowPopup();
108 }
109 else
110 {
111 PRINTLOG(TEXT("QuestionnaireData is invalid"));
112 KLingoNetwork->RequestWriteQuestions(FResponseWriteQuestionDelegate::CreateUObject(this, &AQuestionnaireKiosk::OnResponseData));
113 }
114 }
115
116 // 마커 변경
117 if (ALingoGameState* GS = GetWorld()->GetGameState<ALingoGameState>())
118 {
119 GS->SetAllCompassVisibility(false);
120 GS->SetCompassVisibilityByTag("FinalResult", true);
121 }
122}
123
124void AQuestionnaireKiosk::OnResponseData(FQuestWriteInfo& InResponseData, bool bWasSuccessful)
125{
126 if (bWasSuccessful)
127 {
128 PRINTLOG(TEXT("--- Write Question Response SUCCESS ---"));
129
130 // 쓰기 퀘스트 json 데이터 받기 요청
131 QuestionnaireData = InResponseData;
132
133 for (int32 i = 1; i <= QuestionnaireData.question.Num(); ++i)
134 {
136 data.Id = i;
137 PRINTLOG(TEXT("%d kor: %s"), i, *data.word_data.kor);
138 PRINTLOG(TEXT("%d answer_kor: %s"), i, *data.answer_kor);
139 }
140
141 // 테스트용 더미 데이터 생성
142 // dCreateTestData(QuestionnaireData);
143
144 // 모든 플레이어의 WriteQuest 진행 상태 설정
145 if (ALingoGameState* GS = GetWorld()->GetGameState<ALingoGameState>())
146 {
147 for (APlayerState* PS : GS->PlayerArray)
148 {
149 if (ALingoPlayerState* LingoPS = Cast<ALingoPlayerState>(PS))
150 {
151 LingoPS->SetWriteQuestIng(true);
152 }
153 }
154 }
155
156 ShowPopup();
157 }
158 else
159 {
160 PRINTLOG(TEXT("--- Write Question Response FAILED ---"));
161 }
162}
163
165{
166 if (auto Popup = UPopupManager::ShowPopupAs<UPopup_Questionnaire>(GetWorld(), EPopupType::Questionnaire))
167 {
168 // 팝업 초기화
169 Popup->InitPopup(QuestionnaireData);
170
171 PRINTLOG(TEXT("[PopupTester] Interview popup opened with %d questions"), QuestionnaireData.question.Num());
172 }
173}
174
175
177{
178 // 질문 1
180 Q1.Id = 1;
181 Q1.word_data.kor = TEXT("밤 몇 시에 잡니까?");
182 Q1.word_data.eng = TEXT("When u sleep?");
183 Q1.word_data.pronunciation = TEXT("bam myeot sie japnikka");
184 Q1.answer = TEXT("23:00");
185 Q1.answer_kor = TEXT("저는 밤 11시에 잡니다.");
186 TestData.question.Add(Q1);
187
188 // 질문 2
190 Q2.Id = 2;
191 Q2.word_data.kor = TEXT("가족이 모두 몇 명입니까?");
192 Q2.word_data.eng = TEXT("How many people are there in your family?");
193 Q2.word_data.pronunciation = TEXT("gajogi modu myeot myeongipnikka");
194 Q2.answer = TEXT("4");
195 Q2.answer_kor = TEXT("가족은 모두 4명입니다.");
196 TestData.question.Add(Q2);
197
198 // 질문 3
200 Q3.Id = 3;
201 Q3.word_data.kor = TEXT("오늘은 며칠입니까?");
202 Q3.word_data.eng = TEXT("What's today's date?");
203 Q3.word_data.pronunciation = TEXT("oneureun myeochiripnikka");
204 Q3.answer = FDateTime::Now().ToString(TEXT("%Y-%m-%d"));
205 Q3.answer_kor = FDateTime::Now().ToString(TEXT("오늘은 %Y년 %m월 %d일입니다."));
206 TestData.question.Add(Q3);
207
208 // 질문 4
210 Q4.Id = 4;
211 Q4.word_data.kor = TEXT("오늘 할 게임은 무엇입니까?");
212 Q4.word_data.eng = TEXT("What game are you going to play today?");
213 Q4.word_data.pronunciation = TEXT("oneul hal geimeun mueosipnikka?");
214 Q4.answer = FDateTime::Now().ToString(TEXT("Peak"));
215 Q4.answer_kor = FDateTime::Now().ToString(TEXT("오늘은 Peak라는 게임을 할 것입니다."));
216 TestData.question.Add(Q4);
217
218 TestData.bIsValid = true;
219}
220
222{
223 // 위젯이 없으면 빌보드화 안 함
224 if (!WidgetGuideComp)
225 return;
226
227 // Visibility 체크 - 보이지 않으면 빌보드화 안 함
228 if (!WidgetGuideComp->IsVisible())
229 return;
230
231 // 카메라 가져오기
232 AActor* Camera = UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0);
233 if (!Camera)
234 return;
235
236 // 카메라를 향하도록 회전 계산
237 FRotator Rotation = UKismetMathLibrary::MakeRotFromXZ( -Camera->GetActorForwardVector(), Camera->GetActorUpVector() );
238 Rotation.Pitch = 0;
239
240 // 위젯 회전 설정
241 WidgetGuideComp->SetWorldRotation(Rotation);
242}
243
245{
246 if (KioskMeshComp)
247 {
248 KioskMeshComp->SetRenderCustomDepth(bShouldShowOutline);
249 }
250}
#define INTERACT_WIDGET_PATH
Declares the player-controlled character actor.
APlayerControl 선언에 대한 Doxygen 주석을 제공합니다.
YiSan 전반에서 사용하는 공용 인터페이스를 선언합니다.
#define PRINTLOG(fmt,...)
Definition GameLogging.h:30
KLingo API 요청을 담당하는 서브시스템을 선언합니다.
Main character driven directly by the player.
TObjectPtr< class UBoxComponent > BoxComp
void OnInteractionTriggered(AActor *Interactor)
TObjectPtr< class UWidgetComponent > WidgetGuideComp
void OnOutlineStateChanged(bool bShouldShowOutline)
virtual void GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > &OutLifetimeProps) const override
TObjectPtr< class UStaticMeshComponent > KioskMeshComp
void OnResponseData(FQuestWriteInfo &InResponseData, bool bWasSuccessful)
TObjectPtr< class UInteractableComponent > InteractableComp
virtual void Tick(float DeltaTime) override
virtual void BeginPlay() override
TObjectPtr< class USceneComponent > RootSceneComp
void CreateTestData(FQuestWriteInfo &TestData)
FQuestWriteInfo QuestionnaireData
TObjectPtr< class UWidgetComponent > WidgetComp
Write 퀘스트 정보 구조체입니다.
bool IsValid() const
구조체 값이 유효한지 여부를 반환합니다.
TArray< FWriteQuestionData > question
Write 질문 및 정답 구조체입니다.
FWriteWordData word_data
FString pronunciation