레벨간에 'Character'를 꼭 Possess를 하지는 않고 관찰하는 형식만 필요한 경우가 있다.
이럴 때 보통 Possess를 하지 않고 'spectator mode'로 컨트롤러를 사용하게 된다.
하지만 캐릭터 별로 구분하여 데이터가 필요한 경우가 있을 수 있다. 내 경우에는 컨트롤러가 굳이 필요하지 않지만 PlayerState로 캐릭터를 구분하여 내부 객체를 탐색해야할 필요가 있었다.
내부 에러가 이상하게 처리되어서 좀 헤멘 부분이 있었는데 이를 포함해서 포스팅에서 아래와 같은 내용을 다루려 한다.
에러 부분은 중요하게 다루진 않을 거지만 에러가 이상한 부분에서 터지는 것이 이상하여 기록한다.
Possess의 구현을 따라가서 PlayerState를 세팅하는 부분의 주요 코드를 보면 다음과 같다.
if (Controller->PlayerState != nullptr)
{
SetPlayerState(Controller->PlayerState);
}
직관적으로 Controller 내부에 PlayerState가 있다면 캐릭터 객체 내부에서 SetPlayerState를 사용하여 Controller의 PlayerState를 그대로 Character에 설정한다.
if (PC->PlayerState)
{
DPC->SetPlayerState(PC->PlayerState);
}
1번을 통해서 알 수 있는 내용이다. 내부 구현과 똑같이 'PC'내부에 'PlayerState'가 있는지 확인하고 캐릭터 객체의 SetPlayerState로 'PC'의 'PlayerState'를 설정한다.
이렇게 하면 언리얼의 Possess과정 없이 PlayerState만 공유하도록 설정할 수 있다.
Possess를 하지 않고 실수로 'Character' 내부에서 GetPlayerState를 호출했는데 해당 부분에서 Error가 발생하는게 아니라 실질적으로 사용하는 부분에서 문제가 발생했다.
int32 PlayerId = GetPlayerState()->GetPlayerId(); // 예상되는 에러 지점
FNetLogger::EditerLog(FColor::Green, TEXT("Local PlayerControlled"));
if (TTM)
{
TTM->SendLargeDataInChunks(
DynamicTextureComponent->CompressTextureDataToEXR(),
PS->GetPlayerId()); // 실제로 에러가 생긴 지점
}
위의 문제 때문에 엉뚱한 부분에서 에러가 생긴다고 착각했고 필요이상으로 시간이 걸렸다.
언리얼 내부적으로 최적화가 이루어진다고 생각된다.