언리얼엔진

[C++] UFUNCTION()

찬이2 2023. 9. 6. 22:03

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가 출력된 것을 볼 수 있다.

BP_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 태그를 추가했는지 확인하자.

 

BP_Cube 블루프린트

오버라이드된 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가 두번 출력되는 것을 볼 수 있다.

BP_Cube 블루프린트

여기서 해당 LogandPrintMeshName 함수가 블루프린트에 존재하는지 여부가 오버라이드의 유무를 구분한다.

그래서 처음 LogandPrintMeshName 함수는 LogAndPrintMeshName_Implementation 함수를 호출하지 않고블루프린트에 정의된 내용을 실행한다.

그리고 다음 부모의 LogandPrintMeshName 함수는 오버라이드하지 않아서 LogAndPrintMeshName_Implementation 함수가 불리며 Log 출력이 실행된다.


CPP에서 블루프린트 값 받아올 때...

블루프린트에서 설정한 내용은 class의 생성자에서 바로 받아올 수 없다.

최소 Construction script부터 바로 받아올 수 있다.

 

Construction에서 미리 인스턴스가 만들어지기 때문이다.