나만의 작은 도서관
[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 되면 해당 캐릭터가 랙돌이 됨.
- ⇒ 대충 컨트롤러가 없는 액터의 물리적 상호작용이 유지된다고 보면 된다.
