받은 3D 모델 구조

tripo로 만든 static mesh를 에디터에 임포트

  • desk (Static Mesh) : 책상 본체, 서랍이 빠질 빈 공간이 있는 형태
  • drawer (Static Mesh) : 서랍 칸, 처음부터 별개의 독립된 메시
    → 둘이 원래 분리돼 있어서 별도 모델링 작업 없이 그대로 사용 가능했음

Desk.h 

baseitem을 상속받은 C++ 클래스로 desk 생성

UCLASS()
class THEROOM_API ADesk : public ABaseItem
{
    GENERATED_BODY()
    
public:
    ADesk();
    virtual void ActivateItem(AActor* Activator) override;
    
protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Desk")
    UStaticMeshComponent* DeskMesh;      // 고정된 책상 본체
    
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Desk")
    UStaticMeshComponent* DrawerMesh;    // 움직이는 서랍
    
    UPROPERTY(BlueprintReadOnly, Category = "Desk")
    bool bIsOpen = false;                // 지금 열려있는지 상태
    
    UFUNCTION(BlueprintImplementableEvent, Category = "Desk")
    void DrawerOpen();   // C++엔 구현 없음, 블루프린트가 채움
    
    UFUNCTION(BlueprintImplementableEvent, Category = "Desk")
    void DrawerClose();  // 마찬가지
};

Desk.cpp

ADesk::ADesk()
{
    DeskMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DeskMesh"));
    DeskMesh->SetupAttachment(Scene);
    
    DrawerMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DrawerMesh"));
    DrawerMesh->SetupAttachment(DeskMesh);   // 서랍은 책상에 종속
    
    ItemType = "Desk";
}

void ADesk::ActivateItem(AActor* Activator)
{
    if (Activator && Activator->ActorHasTag("Player"))
    {
        bIsOpen = !bIsOpen;   // 상태 반전
        
        if (bIsOpen)
            DrawerOpen();
        else
            DrawerClose();
    }
}

 

에디터 작업 : BP_Desk

  • ADesk를 부모로 하는 블루프린트 생성
  • DeskMesh에 desk 메시, DrawerMesh에 drawer 메시 연결
  • 닫힌 위치 직접 찾기: DrawerMesh를 뷰포트에서 드래그해서 열린 모습이 되는 위치를 탐색

    • 닫힌 위치: (5, 35, 29)
    • 열린 위치: (30, 35, 29) — X축으로 25만큼 슬라이드

5. Timeline 구성 (OpenTimeline) 

EventGraph 열어서 Event DrawerOpen 검색해서 그 이벤트 노드 추가(close도)
그리고 Add Timeline 검색해서 Timeline 노드 생성

  • Float Track DrawOpen 추가, 키 두 개 찍음: (0초, 값 0) → (0.5초, 값 1)
  • 이 0~1 값을 닫힘→열림 진행률로 사용

6. EventGraph 노드 연결

 

 

주의할 점

Timeline의 Update 실행 핀을 Set Relative Location에 연결하지 않으면, 데이터 흐름은 다 맞아도 매 프레임 갱신이 안 일어나서 아무 움직임도 안 보임 : 데이터 연결(파란/주황 선)과 실행 연결(흰색 선)은 별개로 챙겨야 함

 


BlueprintImplementableEvent

C++에서는 함수 선언만 하고 구현을 안 채움 → 블루프린트 그래프의 Event 노드가 그 신호를 받아서 실제 동작(Timeline 재생)을 채움. C++은 "언제 신호를 보낼지"(로직)만 책임지고, 블루프린트는 "신호를 받으면 뭘 보여줄지"(시각적 표현)를 책임지는 분업

+ Recent posts