나만의 작은 도서관

[TIL][C++] 251107 MMO 서버 개발 132일차: 블루프린트는 오버로딩을 지원하지 않는다, TSubclassOf에서 들어있는 클래스 정보 가져오기, 기타 등등... 본문

Today I Learn

[TIL][C++] 251107 MMO 서버 개발 132일차: 블루프린트는 오버로딩을 지원하지 않는다, TSubclassOf에서 들어있는 클래스 정보 가져오기, 기타 등등...

pledge24 2025. 11. 8. 23:43
주의사항: 해당 글은 일기와 같은 기록용으로, 다듬지 않은 날것 그대로인 글입니다. 

[언리얼] 블루프린트는 오버로딩을 지원하지 않는다.

  • C++함수는 오버로딩을 지원하기 때문에 아래와 같이 작성하는 것이 가능하다.
AMonster* SpawnMonster(int32 TemplateId, const FTransform& Transform);
AMonster* SpawnMonster(int32 TemplateId, const FVector& Location, const FRotator& Rotation);
  • 위 두 SpawnMonster는 서로 다른 시그니처를 가진 함수이기 때문에 내부적으로 다른 함수로 취급하게 된다. 그런데 이런 오버로딩 기능이 블루프린트에서는 지원하지 않는다. 따라서, 아래와 같은 코드는 오류가 발생한다.
UFUNCTION(BlueprintCallable, Category="Spawn")
AMonster* SpawnMonster(int32 TemplateId, const FTransform& Transform);

UFUNCTION(BlueprintCallable, Category="Spawn")
AMonster* SpawnMonster(int32 TemplateId, const FVector& Location, const FRotator& Rotation);

 


[언리얼] TSubclassOf에서 들어있는 클래스 정보 가져오기

  • TsubclassOf는 내부적으로 UClass* 포인터를 들고 있다. 이 포인터를 통해 저장된 클래스 정보에 접근할 수 있다. UClass*는 Get() 함수를 통해 얻을 수 있다.
  • 참고로 BP 클래스인 경우 일반적으로 이름 뒤에 '_C'가 붙습니다.
// TSubclassOf<AActor>타입
if(MonsterBPClass)
{
	UClass* ClassRef = MonsterBPClass.Get();
	
	// 1) 클래스 이름 반환 UClass::GetName()
	// FString을 반환한다.
	FString ClassName = ClassRef->GetName();
	
	// 예: "BP_Goblin_C"
  UE_LOG(LogTemp, Warning, TEXT("Class Name: %s"), *ClassName);   
  
  // 2) 클래스 파일 전체 경로 반환 UClass::GetFullName()
  // 똑같이 FString을 반환한다.
  FString FullClassName = ClassRef->GetFullName();
  
  // 예: "BlueprintGeneratedClass /Game/Blueprints/BP_Goblin.BP_Goblin_C"
  UE_LOG(LogTemp, Warning, TEXT("Full Class Name: %s"), *FullClassName);   
  
  // 3) 클래스 파일 상대 경로 반환 UClass::GetPathName()
  // 똑같이 FString을 반환한다.
  FString ClassPathName = MonsterBPClass->GetPathName();
    
  // 예: "/Game/Blueprints/BP_Goblin.BP_Goblin_C"
  UE_LOG(LogTemp, Warning, TEXT("Class Path Name: %s"), *ClassPathName);
}

 

 


[언리얼] 기타 알게 된 내용

 

UPROPERTY 매크로에 Category 지정자를 사용할 때, 값을 큰따옴표 없이 적는 것은 무슨 의미일까?

  • 보통 큰따옴표를 적어주는데, 큰따옴표가 없다고 특별한 의미가 있는 건 아니고, 공백이나 특수 문자가 포함되지 않는 값일 때 사용한다. 큰따옴표가 공백이나 특수 문자가 포함된 전체 문자열을 하나의 토큰으로 인식하도록 해주는 역할이기 때문.
UPROPERTY(Category = MyCategory) // 문제없음
UPROPERTY(Category = My Category) // 문제 있음
UPROPERTY(Category = "My Category") // 문제 없음

 

 

meta = (AllowPrivateAccess = "true")는 무슨 용도일까?

  • TPS 템플릿을 C++로 받으면 아래와 같이 InputAction의 UPROPERTY가 설정되어 있는 것을 볼 수 있는데,
private:
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputAction* JumpAction;
	
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputAction* MoveAction;
	
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
	UInputAction* LookAction;
  • 여기서 meta = (AllowPrivateAccess = "true")는 “C++ 클래스의 private로 선언된 변수를 BP에서 접근 가능”하도록 하는 용도이다.
  • 왜 하위 클래스인 BP에서 상위 C++ 클래스의 priavate 변수에 접근할 수 있도록 허용하는가? 의문이 들기는 하는데, 아래와 같은 이유로 사용한다고 한다.
    • C++ 캡슐화 유지: C++ 코드 내는 private로 유지하여 C++ 코드에서 직접 접근하여 변경하는 것을 막고 싶을 때(BP만 제외하고)

 

 

UPROPERTY()에서 EditAnywhere, BlueprintReadOnly를 동시에 사용하면 정확히 어떤 효과가 나는가?

  • 해당 변수는 에디터에서 수정 가능, But 블루프린트 스크립트에서 쓰기 불가능(읽기 전용)
    • 에디터에서의 효과 EditAnywhere: 디테일 패널에 해당 변수가 노출됨 + 해당 변수가 속한 클래스의 어떤 인스턴스에서든(Ex. 레벨에 배치된 인스턴스 or BP 기본값) 쓰기 작업 가능
    • BP에서의 효과(BlueprintReadOnly): 블루프린트에서 읽는 것만 가능하고 쓰는 것은 안됨. 즉, Get만 가능하고 Set은 안된다.

 

 

 

블루프린트 노드에서 UE_LOG 역할을 하는 노드는?

  • 따로 있는 게 아니라 똑같이 Print String 노드를 사용하면 된다. 이때 Development Only를 열어서 Print to Screen만 끄고 Print to Log만 켜주면 된다. 그러면 뷰포트에는 출력이 안되고 Output Log에만 해당 로그가 출력된다. (UE_LOG처럼)

 

 

데이터 테이블 순회 방법 재정리(?)

 

블루프린트 버전

  • Get Data Table Row Names 노드 사용
    • DT에 있는 모든 행의 이름이 FName 배열에 넣어져 반환됨.
  • For Each Loop 노드 연결
    • 반복문을 돈다.
  • Get Data Table Row
    • 행의 이름(FName)으로 행을 반환받는다.

C++ 버전

TArray<FMonsterData*> AllRows;
static const FString Context(TEXT("LoadMonsterAsset"));

MonsterDataTable->GetAllRows<FMonsterData>(Context, AllRows);
for (const FMonsterData* Row : AllRows)
{
    if (!Row)
}

 

 

언리얼 bRunPhysicsWithNoController의 역할

  • 액터(Actor)에 컨트롤러가 연결되어 있지 않은 상태에서 물리 시뮬레이션을 계속 돌릴 건지 여부를 결정하는 플래그. 기본값은 false로 되어있다.

true로 설정되었을 때의 효과

  • 컨트롤 중인 캐릭터가 들고 있던 검이 UnPossess 되면, 중력의 영향을 받으며 떨어짐
  • 플레이어의 캐릭터가 죽어 컨트롤러가 UnPossess 되면 해당 캐릭터가 랙돌이 됨.
    • ⇒ 대충 컨트롤러가 없는 액터의 물리적 상호작용이 유지된다고 보면 된다.