[C++] UFUNCTION()
UFUNCTION(...)
새로운 리플렉션의 방법 중 하나이다.
public:
UFUNCTION(BlueprintCallable) //블루프린트 사용
void LogMeshName();
UFUNCTION(BlueprintImplementableEvent) //오버라이드
void PrintMeshName();
UFUNCTION(BlueprintNativeEvent) //조금 다른 오버라이드
void LogAndPrintMeshName();
virtual void LogAndPrintMeshName_Implementation();
함수를 선언하고, 해당 함수에 적용하는 방식으로 사용하게 된다.
- BlueprintCallable : 블루프린트에서 함수를 불러 사용할 수 있다.
- BlueprintImplementableEvent : Implementable은 구현하다는 뜻으로, 원래라면 UFUNCTION() 태그의 함수는 선언 후 정의를 해야만 한다. 하지만 이 태그를 사용하면 함수의 정의를 자동으로
완성시켜주기 때문에 선언 후 바로 빌드가 가능하다.
이미 정의해둔 함수에 사용하면 중복 오류가 발생하니 주의하자.
- BlueprintNativeEvent : Implementable과 같이 자동완성이 되지만, 블루프린트에서 오버라이드한 내용이 없다면 밑의
Implementation() 함수를 호출한다.
LogMeshName() 함수의 정의 - BlueprintCallable
이어서 LogMeshName()함수의 정의를 한다. 여기서 언리얼 에디터에서 Log를 작성하는 법도 알아보자.
void ACube::LogMeshName()
{
UE_LOG(LogTemp, Log, TEXT("%s"), *Mesh->GetStaticMesh()->GetFName().ToString());
}
UE_LOG를 통해 언리얼 에디터의 출력 로그에 원하는 값을 출력시킬 수 있다.
* 여기서 *Mesh를 사용하지만, 멤버접근연산자로 ->를 사용하는 이유는, 멤버접근연산자의 우선순위가 더 높기 때문에
최종적으로 ToString()이 영향을 받기 때문이다.
빌드 후에, 언리얼 에디터 BP_Cube 블루프린트에서 BeginPlay와 LogMeshName() 함수를 연결하여 플레이하면
LogMeshName()함수가 실행되면서 출력 로그에 LogTemp : Cube가 출력된 것을 볼 수 있다.
PrintMeshName() 함수 - BlueprintImplementableEvent
void ACube::BeginPlay()
{
Super::BeginPlay();
PrintMeshName(); //Cube클래스의 BeginPlay()에 PrintMeshName()함수 호출만 추가
LoadObject<UStaticMesh>(this, TEXT("StaticMesh'/Game/Cube.Cube'"));
}
PrintMeshName함수의 호출을 위해 Cube클래스 BeginPlay에 함수 호출만 추가해주고, 함수 정의를 하지않고 빌드했다.
이후 BP_Cube 블루프린트에서 함수 오버라이드 목록을 보면 방금 선언한 PrintMeshName 함수가 있는 것을 볼 수 있다.
* 에디터로 넘어가기 전에 Mesh변수의 UPROPERTY()에 BlueprintReadOnly 태그를 추가했는지 확인하자.
오버라이드된 PrintMeshName()함수의 정의는 블루프린트에서 해주는 것이다.
위와같이 정의한 후, 플레이하면 화면에 Cube가 출력되는 것을 볼 수 있다.
LogAndPrintMeshName_Implementation() 함수 - BlueprintNativeEvent
BlueprintNativeEvent 태그가 붙은 LogAndPrintMeshI()함수는 자동완성이 되기 때문에 정의하지 않는다.
그래서 따로 정의를 담당할 함수 LogAndPrintMeshName_Implementation()를 밑에 추가하고 정의해줄 것이다.
void ACube::BeginPlay()
{
Super::BeginPlay();
PrintMeshName();
LogAndPrintMeshName(); //LogAndPrintMeshName()함수의 호출만 넣어줌
LoadObject<UStaticMesh>(this, TEXT("StaticMesh'/Game/Cube.Cube'"));
}
...
//정의를 담당할 LogAndPrintMeshName_Implementation()함수의 정의
void ACube::LogAndPrintMeshName_Implementation()
{
LogMeshName();
}
LogAndPrintMeshName_Implementation()함수를 정의하고 BeginPlay()에 LogAndPrintMeshName()함수 호출만 넣었다.
빌드하고 BP_Cube 블루프린트의 함수 오버라이드 목록에 LogAndPrintMeshName() 함수가 추가됬다.
블루프린트에서 LogAndPrintMeshName() 함수의 정의를 구현하여 플레이해보면 화면에 Cube가 두 번 출력되고,
출력 로그에도 LogTemp : Cube가 두번 출력되는 것을 볼 수 있다.
여기서 해당 LogandPrintMeshName 함수가 블루프린트에 존재하는지 여부가 오버라이드의 유무를 구분한다.
그래서 처음 LogandPrintMeshName 함수는 LogAndPrintMeshName_Implementation 함수를 호출하지 않고블루프린트에 정의된 내용을 실행한다.
그리고 다음 부모의 LogandPrintMeshName 함수는 오버라이드하지 않아서 LogAndPrintMeshName_Implementation 함수가 불리며 Log 출력이 실행된다.
CPP에서 블루프린트 값 받아올 때...
블루프린트에서 설정한 내용은 class의 생성자에서 바로 받아올 수 없다.
최소 Construction script부터 바로 받아올 수 있다.
Construction에서 미리 인스턴스가 만들어지기 때문이다.