KLingo Project Documentation 1.0.0
Unreal Engine 5.6 C++ Project Documentation
로딩중...
검색중...
일치하는것 없음
UInteractionSystem.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
9
10#include "APlayerActor.h"
11#include "APlayerControl.h"
12#include "GameLogging.h"
14#include "UGameSoundManager.h"
15#include "Camera/PlayerCameraManager.h"
16#include "GameFramework/PlayerController.h"
17
18UInteractionSystem::UInteractionSystem()
19{
20 PrimaryComponentTick.bCanEverTick = true;
21 PrimaryComponentTick.TickGroup = TG_PostUpdateWork;
22}
23
24void UInteractionSystem::BeginPlay()
25{
26 Super::BeginPlay();
27
28 // Owner PlayerActor 캐싱
29 OwnerPlayer = Cast<APlayerActor>(GetOwner());
30 if (!OwnerPlayer)
31 {
32 PRINTLOG( TEXT("UInteractionSystem: Owner is not APlayerActor!"));
33 SetComponentTickEnabled(false);
34 }
35}
36
37void UInteractionSystem::TickComponent(float DeltaTime, ELevelTick TickType,
38 FActorComponentTickFunction* ThisTickFunction)
39{
40 Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
41
42 // 타겟 감지
43 CurrentTarget = DetectInteractableTarget();
44
45 // 디버그 표시
46 if (bShowDebugInfo && CurrentTarget)
47 {
48 CurrentTarget->ShowDebugInfo(OwnerPlayer);
49 }
50}
51
52void UInteractionSystem::TryInteract()
53{
54 if (!CurrentTarget || !CurrentTarget->bCanInteract)
55 return;
56
57 // PRINT_STRING(TEXT("부엉 부엉 %s"), *CurrentTarget->GetName());
58 //
59 // PRINT_STRING(TEXT("부엉 부엉 %s"), *OwnerPlayer->GetName());
60 // 타입별 처리
61 switch (CurrentTarget->InteractionType)
62 {
63 // case EInteractionType::PickUp:
64 // PRINT_STRING(TEXT("부엉 부엉 %s"), *OwnerPlayer->GetName());
65 // TryPickUp();
66 // break;
67
68 case EInteractionType::Button:
69 // PRINT_STRING(TEXT("부엉 부엉 %s"), *OwnerPlayer->GetName());
70 PRINTLOG(TEXT("UInteractionSystem: Interacting with %s, %s"), *GetOwner()->GetName(), *OwnerPlayer->GetName());
71 CurrentTarget->TriggerInteraction(OwnerPlayer);
72
73 UGameSoundManager::Get(GetWorld())->PlaySound2D( EGameSoundType::UI_Interation);
74 break;
75
76 case EInteractionType::Kiosk:
77 PRINTLOG(TEXT("UInteractionSystem: Interacting with %s"), *GetOwner()->GetName());
78 if (APlayerControl* pc = Cast<APlayerControl>(OwnerPlayer->GetController()))
79 {
80 pc->Client_InteractKiosk();
81 }
82 break;
83
84 default:
85 break;
86 }
87}
88
89void UInteractionSystem::TryPickUp()
90{
91 // 이미 들고 있으면 무시
92 if (HoldingInteractable)
93 return;
94
95 // CurrentTarget = DetectInteractableTarget();
96
97 // 타겟이 PickUp 타입인지 확인
98 if (!CurrentTarget || CurrentTarget->InteractionType != EInteractionType::PickUp)
99 return;
100
101 // 유효성 검사 강화
102 if (!IsValid(CurrentTarget))
103 {
104 PRINTLOG( TEXT("UInteractionSystem: CurrentTarget is invalid!"));
105 CurrentTarget = nullptr;
106 return;
107 }
108
109 AActor* TargetOwner = CurrentTarget->GetOwner();
110 if (!TargetOwner || !IsValid(TargetOwner))
111 {
112 PRINTLOG( TEXT("UInteractionSystem: Target owner is null or invalid!"));
113 return;
114 }
115
116 // 로그 출력 (PickUp 호출 전)
117 PRINTLOG( TEXT("UInteractionSystem: Picking up %s"), *TargetOwner->GetName());
118
119 HoldingInteractable = CurrentTarget;
120 HoldingInteractable->PickUp(OwnerPlayer);
121
122 UGameSoundManager::Get(GetWorld())->PlaySound2D( EGameSoundType::UI_Interation);
123}
124
125void UInteractionSystem::TryDrop()
126{
127 if (!HoldingInteractable)
128 return;
129
130 // 유효성 검사
131 if (!IsValid(HoldingInteractable))
132 {
133 PRINTLOG( TEXT("UInteractionSystem: HoldingInteractable is invalid!"));
134 HoldingInteractable = nullptr;
135 return;
136 }
137
138 // 로그 출력 (Drop 호출 전)
139 AActor* DroppedOwner = HoldingInteractable->GetOwner();
140 if (DroppedOwner && IsValid(DroppedOwner))
141 {
142 PRINTLOG( TEXT("UInteractionSystem: Dropping %s"), *DroppedOwner->GetName());
143 }
144
145 HoldingInteractable->Drop();
146 HoldingInteractable = nullptr;
147
148 PRINTLOG( TEXT("UInteractionSystem: Drop complete"));
149}
150
151void UInteractionSystem::RegisterInteractable(UInteractableComponent* Interactable)
152{
153 if (!Interactable || !IsValid(Interactable))
154 {
155 PRINTLOG( TEXT("UInteractionSystem: Attempted to register null/invalid interactable"));
156 return;
157 }
158
159 if (NearbyInteractables.Contains(Interactable))
160 return;
161
162 NearbyInteractables.Add(Interactable);
163}
164
165void UInteractionSystem::UnregisterInteractable(UInteractableComponent* Interactable)
166{
167 if (!Interactable)
168 return;
169
170 NearbyInteractables.Remove(Interactable);
171
172 // 현재 타겟이었다면 해제
173 if (CurrentTarget == Interactable)
174 {
175 CurrentTarget = nullptr;
176 }
177}
178
179USceneComponent* UInteractionSystem::GetHoldPosition() const
180{
181 return OwnerPlayer ? OwnerPlayer->HoldPosition : nullptr;
182}
183
184UInteractableComponent* UInteractionSystem::DetectInteractableTarget()
185{
186 // 근처에 상호작용 가능한 객체가 없으면 nullptr
187 if (NearbyInteractables.Num() == 0)
188 return nullptr;
189
190 // LineTrace 실행
191 FHitResult HitResult;
192 if (!PerformCenterLineTrace(HitResult))
193 return nullptr;
194
195 // Hit된 액터에서 InteractableComponent 찾기
196 AActor* HitActor = HitResult.GetActor();
197 if (!HitActor)
198 return nullptr;
199
200 UInteractableComponent* InteractComp = HitActor->FindComponentByClass<UInteractableComponent>();
201 if (!InteractComp)
202 return nullptr;
203
204 // NearbyInteractables에 포함되어 있는지 확인 (범위 내인지 검증)
205 if (NearbyInteractables.Contains(InteractComp))
206 {
207 return InteractComp;
208 }
209
210 return nullptr;
211}
212
213bool UInteractionSystem::PerformCenterLineTrace(FHitResult& OutHit)
214{
215 if (!OwnerPlayer)
216 return false;
217
218 // 플레이어 컨트롤러 가져오기
219 APlayerController* PC = Cast<APlayerController>(OwnerPlayer->GetController());
220 if (!PC)
221 return false;
222
223 APlayerCameraManager* CameraManager = PC->PlayerCameraManager;
224 if (!CameraManager)
225 return false;
226
227 FVector CameraLocation = CameraManager->GetCameraLocation();
228 FVector CameraForward = CameraManager->GetCameraRotation().Vector();
229
230 // 레이 트레이스 시작/끝 지점
231 FVector TraceStart = CameraLocation;
232 FVector TraceEnd = TraceStart + (CameraForward * InteractionDistance);
233
234 // Ray trace 실행
235 bool bHit = GetWorld()->LineTraceSingleByChannel(
236 OutHit, TraceStart, TraceEnd, ECC_Visibility
237 );
238
239 // 디버그 라인
240 if (bShowDebugInfo)
241 {
242 DrawDebugLine(
243 GetWorld(), TraceStart, TraceEnd,
244 bHit ? FColor::Green : FColor::Red,
245 false, 0.0f, 0, 0.5f
246 );
247 }
248
249 return bHit;
250}
Declares the player-controlled character actor.
APlayerControl 선언에 대한 Doxygen 주석을 제공합니다.
YiSan 전반에서 사용하는 공용 인터페이스를 선언합니다.
#define PRINTLOG(fmt,...)
Definition GameLogging.h:30
UGameSoundManager 클래스를 선언합니다.
플레이어의 상호작용 감지 및 처리 시스템