KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
CompassWidget.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
4#include "CompassWidget.h"
5
6#include "Components/CanvasPanel.h"
7#include "Components/CanvasPanelSlot.h"
8#include "Components/Image.h"
9#include "Components/TextBlock.h"
10
12{
13 Super::NativeConstruct();
14
15 if (MarkerTextureMap.Num() == 0)
16 {
18 LoadObject<UTexture2D>(nullptr, TEXT("/Game/CustomContents/UI/Texture/Resource/Icon_Listen.Icon_Listen")));
20 LoadObject<UTexture2D>(nullptr, TEXT("/Game/StarterBundle/Image/mark1.mark1")));
22 LoadObject<UTexture2D>(nullptr, TEXT("/Game/CustomContents/UI/Texture/Resource/Icon_Whitney.Icon_Whitney")));
24 LoadObject<UTexture2D>(nullptr, TEXT("/Game/CustomContents/UI/Texture/Resource/resource_score.resource_score")));
26 LoadObject<UTexture2D>(nullptr, TEXT("/Game/CustomContents/UI/Texture/Resource/Icon_Overall.Icon_Overall")));
28 LoadObject<UTexture2D>(nullptr, TEXT("/Game/CustomContents/UI/Texture/Resource/Icon_RedOwl.Icon_RedOwl")));
29 }
30}
31
32void UCompassWidget::RotateCompass(float ZRotation)
33{
34 FVector2D DesiredSize = Img_Compass->GetDesiredSize();
35
36 UCanvasPanelSlot* CanvasSlot = Cast<UCanvasPanelSlot>(Img_Compass->Slot);
37 if (CanvasSlot)
38 {
39 float PositionX = -ZRotation * (DesiredSize.X / 360.f);
40 CanvasSlot->SetPosition(FVector2D(PositionX, 0.f));
41 }
42}
43
45{
46 UImage* NewMarker = NewObject<UImage>(this);
47 if (NewMarker)
48 {
49 UTexture2D* CompassTex = GetTextureForMarkerType(MarkerType);
50 if (CompassTex)
51 {
52 NewMarker->SetBrushFromTexture(CompassTex);
53 }
54
55 Pnl_Compass->AddChild(NewMarker);
56
57 UCanvasPanelSlot* MarkerSlot = Cast<UCanvasPanelSlot>(NewMarker->Slot);
58 if (MarkerSlot)
59 {
60 MarkerSlot->SetAnchors(FAnchors(0.5, 0.5, 0.5, 0.5));
61 MarkerSlot->SetSize(FVector2D(60.f, 60.f));
62 MarkerSlot->SetAlignment(FVector2D(0.5f, 0.5f));
63 MarkerSlot->SetPosition(FVector2D(0.f, 0.f));
64 }
65
66 // 거리 텍스트 생성
67 UTextBlock* DistanceText = NewObject<UTextBlock>(this);
68 if (DistanceText)
69 {
70 Pnl_Compass->AddChild(DistanceText);
71
72 UCanvasPanelSlot* TextSlot = Cast<UCanvasPanelSlot>(DistanceText->Slot);
73 if (TextSlot)
74 {
75 TextSlot->SetAnchors(FAnchors(0.5, 0.5, 0.5, 0.5));
76 TextSlot->SetSize(FVector2D(100.f, 20.f));
77 TextSlot->SetAlignment(FVector2D(0.5f, -0.8f)); // 하단 중앙 정렬
78 TextSlot->SetPosition(FVector2D(0.f, -5.f)); // 마커 위에 배치
79 TextSlot->SetZOrder(100); // 최상위로 설정
80 }
81
82 // 텍스트 스타일 설정
83 FSlateFontInfo FontInfo = DistanceText->GetFont();
84 FontInfo.Size = 14;
85 DistanceText->SetFont(FontInfo);
86 DistanceText->SetJustification(ETextJustify::Center);
87 DistanceText->SetColorAndOpacity(FLinearColor::White);
88 DistanceText->SetText(FText::FromString(TEXT("0m")));
89 DistanceText->SetVisibility(ESlateVisibility::Visible);
90
91 // 텍스트에 그림자 추가 (가독성 향상)
92 DistanceText->SetShadowOffset(FVector2D(1.f, 1.f));
93 DistanceText->SetShadowColorAndOpacity(FLinearColor::Black);
94
95 MarkerDistanceMap.Add(NewMarker, DistanceText);
96 }
97
98 Markers.Add(NewMarker);
99
100 return NewMarker;
101 }
102
103 return nullptr;
104}
105
107{
108 UTexture2D** FoundTexture = MarkerTextureMap.Find(MarkerType);
109 if (FoundTexture && *FoundTexture)
110 {
111 return *FoundTexture;
112 }
113
114 return LoadObject<UTexture2D>(nullptr, TEXT("/Game/StarterBundle/Image/mark1.mark1"));
115}
116
117void UCompassWidget::SetMarkerPosition(UImage* InMarker, float TargetRotation, bool bSideLock)
118{
119 float CompassSize = Img_Compass->GetDesiredSize().X;
120 float MarkerRotation = TargetRotation * (CompassSize/360.f);
121
122 UCanvasPanelSlot* MarkerSlot = Cast<UCanvasPanelSlot>(InMarker->Slot);
123 if (MarkerSlot)
124 {
125 FVector2D FinalPosition = FVector2D::ZeroVector;
126
127 if (!bSideLock)
128 {
129 FinalPosition = FVector2D(MarkerRotation, 0.f);
130 MarkerSlot->SetPosition(FinalPosition);
131 }
132 else
133 {
134 UCanvasPanelSlot* CompassSlot = Cast<UCanvasPanelSlot>(Pnl_Compass->Slot);
135 if (CompassSlot)
136 {
137 float PositionX = (CompassSlot->GetSize().X / 2);
138
139 if (FMath::Abs(MarkerRotation) < PositionX)
140 {
141 FinalPosition = FVector2D(MarkerRotation, 0.f);
142 }
143 else if (MarkerRotation > PositionX)
144 {
145 FinalPosition = FVector2D(PositionX, 0.f);
146 }
147 else
148 {
149 FinalPosition = FVector2D(-PositionX, 0.f);
150 }
151
152 MarkerSlot->SetPosition(FinalPosition);
153 }
154 }
155
156 // 거리 텍스트도 같이 이동
157 if (UTextBlock** FoundText = MarkerDistanceMap.Find(InMarker))
158 {
159 UCanvasPanelSlot* TextSlot = Cast<UCanvasPanelSlot>((*FoundText)->Slot);
160 if (TextSlot)
161 {
162 TextSlot->SetPosition(FVector2D(FinalPosition.X, -5.f)); // 마커 위에 배치
163 }
164 }
165 }
166}
167
168void UCompassWidget::SetMarkerDistance(UImage* InMarker, float Distance)
169{
170 if (UTextBlock** FoundText = MarkerDistanceMap.Find(InMarker))
171 {
172 // 거리를 미터 단위로 변환 (언리얼은 센티미터 단위)
173 float DistanceInMeters = Distance / 100.f;
174
175 FString DistanceStr;
176 if (DistanceInMeters >= 1000.f)
177 {
178 // 1km 이상이면 km 단위로 표시
179 DistanceStr = FString::Printf(TEXT("%.1fkm"), DistanceInMeters / 1000.f);
180 }
181 else
182 {
183 // 1m 이상이면 m 단위로 표시
184 DistanceStr = FString::Printf(TEXT("%.0fm"), DistanceInMeters);
185 }
186
187 (*FoundText)->SetText(FText::FromString(DistanceStr));
188 }
189}
190
191void UCompassWidget::SetMarkerVisibility(UImage* InMarker, ESlateVisibility InVisibility)
192{
193 if (InMarker)
194 {
195 InMarker->SetVisibility(InVisibility);
196 }
197
198 // 거리 텍스트도 같은 Visibility 적용
199 if (UTextBlock** FoundText = MarkerDistanceMap.Find(InMarker))
200 {
201 if (*FoundText)
202 {
203 (*FoundText)->SetVisibility(InVisibility);
204 }
205 }
206}
207
208// void UCompassWidget::UpdateCompassMarkers(TArray<FCompassInfo>& CompassInfos)
209// {
210// for (int32 i=0; i<CompassMarkers.Num(); i++)
211// {
212// if (Markers[i])
213// {
214// SetMarkerPosition(Markers[i], CompassMarkers[i], false);
215// Markers[i]->SetVisibility(ESlateVisibility::Visible);
216// }
217// else
218// {
219// UImage* NewImage = AddCompassMarker();
220// SetMarkerPosition(NewImage, CompassMarkers[i], false);
221// }
222// }
223//
224// if (CompassMarkers.Num() < Markers.Num())
225// {
226// for (int32 i=CompassMarkers.Num(); i<Markers.Num(); i++)
227// {
228// Markers[i]->SetVisibility(ESlateVisibility::Hidden);
229// }
230// }
231// }
232
233
234
235
ECompassMarkerType
virtual void NativeConstruct() override
TArray< UImage * > Markers
void RotateCompass(float ZRotation)
class UImage * Img_Compass
UImage * AddCompassMarker(ECompassMarkerType MarkerType)
TMap< UImage *, class UTextBlock * > MarkerDistanceMap
마커별 거리 텍스트 매핑
TMap< ECompassMarkerType, UTexture2D * > MarkerTextureMap
void SetMarkerDistance(UImage *InMarker, float Distance)
마커 거리 설정 (미터 단위)
void SetMarkerPosition(UImage *InMarker, float TargetRotation, bool bSideLock)
void SetMarkerVisibility(UImage *InMarker, ESlateVisibility InVisibility)
마커와 거리 텍스트의 Visibility 동시 설정
class UCanvasPanel * Pnl_Compass
UTexture2D * GetTextureForMarkerType(ECompassMarkerType MarkerType)