ADoor가 ADarkLetter를 직접 참조해서 그 편지가 읽혔는지 물어보고 그 결과에 따라 나눈다
1. DarkLetter에 읽음 상태 추가
.h
UPROPERTY(BlueprintReadOnly, Category = "Letter")
bool bRead = false;
public:
bool IsRead() const;
.cpp
bool ADarkLetter::IsRead() const
{
return bRead;
}
ActivateItem에서 편지를 처음 펼치는 순간에 아래 코드를 추가한다.
else if (LetterWidgetClass)
{
...
bRead = true; // 한번 열리면 영구히 true (닫아도 false로 안 돌아감)
}
2. Door.h : 편지 참조와 잠김 메시지 변수 추가
class ADarkLetter; // 전방 선언
class UInteractionWidget; // 전방 선언
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Door")
ADarkLetter* RequiredLetter;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Door")
TSubclassOf<UInteractionWidget> LockedMessageClass;
UPROPERTY()
UInteractionWidget* LockedWidgetInstance;
3. Door.cpp : ActivateItem
void ADoor::ActivateItem(AActor* Activator)
{
if (Activator && Activator->ActorHasTag("Player"))
{
ATheRoomCharacter* PlayerCharacter = Cast<ATheRoomCharacter>(Activator);
if (!PlayerCharacter) return;
if (RequiredLetter && !RequiredLetter->IsRead())
{
// 편지와 동일 패턴
if (LockedWidgetInstance)
{
LockedWidgetInstance->RemoveFromParent();
LockedWidgetInstance = nullptr;
PlayerCharacter->ShowInteraction();
}
else if (LockedMessageClass)
{
LockedWidgetInstance = CreateWidget<UInteractionWidget>(GetWorld(), LockedMessageClass);
LockedWidgetInstance->AddToViewport();
PlayerCharacter->HideInteraction();
}
}
else
{
// 읽었으면 (또는 편지 연결 안 됐으면) → 레벨 전환
UGameplayStatics::OpenLevel(this, FName("BrightRoom"));
}
}
}
4. 에디터
WBP_Interaction를 Duplicate해서 WBP_DoorLocked를 만들고 텍스트만 "문이 잠겨있다"로 바꿈
그리고 레벨(DarkRoom)에 배치된 Door 액터를 선택해서 Details 패널에서 RequiredLetter에 레벨에 배치된 BP_DarkLetter 인스턴스를 LockedMessageClass에 WBP_DoorLocked를 연결했다
새롭게 알게된 것
클래스 vs 인스턴스
RequiredLetter 같은 참조는 블루프린트 클래스 디폴트, 즉 설계도 자체에서는 설정할 수 없다는 걸 배웠다
설정은 레벨에 실제로 배치된 그 인스턴스에서만 가능하다
이유를 알아보니 설계도는 "이 클래스에 속하는 모든 객체가 보편적으로 어때야 하는가"를 정의하는 자리다.
RequiredLetter는 "이 문이 기다리는 편지는 바로 저 편지다"라는 특정 레벨에만 존재하는 구체적인 사실이기 때문에 설계도 수준에서는 의미를 가질 수 없다
(같은 Door 클래스를 다른 레벨에 또 배치한다면 그 문은 또 다른 편지를 기다릴 수도 있어야 하니까)
LockedMessageClass처럼 TSubclassOf로 잡은 변수는 "어떤 종류의 위젯을 쓸지"라는 보편적인 설계 정보라서 클래스 디폴트에서도 지정할 수 있지만, ADarkLetter* 같은 특정 액터 참조는 레벨 위에 놓인 그 인스턴스를 가리켜야 하므로 레벨 인스턴스에서만 채울 수 있다.
'프로젝트 > The Room (방탈출 게임)' 카테고리의 다른 글
| 상호작용 시스템 개선: 오버랩 콜리전에서 라인 트레이스 방식으로 전환 (0) | 2026.06.23 |
|---|---|
| 상호작용하면 열리는 서랍장 만들기 (0) | 2026.06.22 |
| 편지 토글과 안내 UI 겹침 문제 해결 (0) | 2026.06.22 |
| UMG로 상호작용 안내 위젯 띄우기 (0) | 2026.06.22 |
| Enhanced Input으로 E키 상호작용 연결하기 (0) | 2026.06.22 |
