ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Unreal] Spectator 에서 스팀 이름 가져오기
    쾌락없는 책임 (공부)/Unreal 2023. 7. 14. 23:28
    반응형

    개요

    일단 이걸 하기 전 Online Subsystem Steam 플러그인을 활용하고 이를 통해 세션을 제작해야 합니다. 이 과정을 거치면 PlayerState에서 PlayerName이 스팀의 닉네임으로 설정됩니다. 그리고 이번 글에서 알려드릴 건 이 스팀 닉네임을 Spectator에서 가져오는 것입니다.

     

     

    Spectator Pawn 에서 관전자를 변경하는 방법

    일단 다른 게임에서 보이듯 죽고 나서 관전할 플레이어를 변경할 수 있는 기능을 구현했습니다. 이는 GameMode에서 Spectator Pawn으로 할당하는 Pawn 클래스에서 관리를 하는데 아래 코드와 같은 모습입니다.

    void AFASpectatorPawn::SpectateNextPlayer()
    {
    	if (APlayerController* PlayerController = GetController<APlayerController>())
    	{
    		PlayerController->ServerViewNextPlayer();
    	}
    }
    
    void AFASpectatorPawn::SpectatePrevPlayer()
    {
    	if (APlayerController* PlayerController = GetController<APlayerController>())
    	{
    		PlayerController->ServerViewPrevPlayer();
    	}
    }

    여기서 플레이어 컨트롤러의 ServerView~~Player를 사용했습니다. 이 함수는 언리얼에서 제공하는 함수로 다음이나 이전 플레이어를 관전하게 도와주는 함수입니다. 이 함수를 호출하면 카메라 시점이 그 플레이어로 넘어가게 되는 것이죠.

     

    void APlayerController::ServerViewNextPlayer_Implementation()
    {
    	if (IsInState(NAME_Spectating))
    	{
    		ViewAPlayer(+1);
    	}
    }
    
    void APlayerController::ServerViewPrevPlayer_Implementation()
    {
    	if (IsInState(NAME_Spectating))
    	{
    		ViewAPlayer(-1);
    	}
    }

    그런데 파고보면 이 두 함스는 결국 ViewAPlayer라는 함수를 사용하고 있고

    void APlayerController::ViewAPlayer(int32 dir)
    {
    	APlayerState* const NextPlayerState = GetNextViewablePlayer(dir);
    
    	if ( NextPlayerState != nullptr )
    	{
    		SetViewTarget(NextPlayerState);
    	}
    }
    
    void APlayerController::SetViewTarget(class AActor* NewViewTarget, struct FViewTargetTransitionParams TransitionParams)
    {
    	if (PlayerCameraManager)
    	{
    		PlayerCameraManager->SetViewTarget(NewViewTarget, TransitionParams);
    	}
    }

    ViewAPlayer는 타고 가면 PlayerCameraManager에서 SetViewTarget을 해주는 것임을 알 수 있습니다. 그렇다면 이렇게 설정된 ViewTarget은 어떻게 가져올 수 있을까요? 바로 플레이어 컨트롤러에서 GetViewTarget을 통해 가져올 수 있습니다.

     

    그러면 죽은 사용자(클라이언트)는 서버에서 ViewAPlayer를 부르면 보고 있는 사용자가 달라질 것이고 카메라는 이제 변경된 ViewTarget을 보게 됩니다.

     

    그러면 스팀 아이디를 불러오기 위해서는 이 ViewTarget에서 PlayerState를 가져오면 되는 것입니다.

    void APlayableController::ViewAPlayer(int32 dir)
    {
    	Super::ViewAPlayer(dir);
    	
    	ClientViewTarget();
    }
    
    void APlayableController::ClientViewTarget_Implementation()
    {
    	if(GetViewTarget())
    	{
    		OnSpectatorViewTargetChanged.Broadcast(GetViewTarget());
    	}
    }

    저의 플레이어 컨트롤러에서 ViewAPlayer를 오버라이드 해 줬고 여기서 제가 만든 함수인 ClientViewTarget을 호출해 줬습니다. ViewAPlayer는 서버에서 불리는 함수니 Client RPC로 설정해 줬습니다.

     

    ClientViewTarget은 단순히 델리게이트를 브로드캐스트만 하는데 여기에 GetViewTarget을 넘겨줍니다.

    void UDeadWidget::ViewTargetChanged(AActor* ViewTarget)
    {
    	if(SpectatedActorName == nullptr)	return;
    
    	if(const auto ViewPawn = Cast<APawn>(ViewTarget))
    	{
    		if(ViewPawn->GetPlayerState())
    		{
    			SpectatedActorName->SetText(FText::FromString(ViewPawn->GetPlayerState()->GetPlayerName()));
    		}
    	}
    }

    그곳에는 이 UI의 함수가 바인딩되어 있는데 여기서 받은 액터를 Pawn으로 변경한 뒤 PlayerState를 가져와야 합니다. Actor에는 그런 게 없으니깐요.

     

    이후 여기서 얻은 PlayerState에서 GetPlayerName을 가져오면 스팀 아이디를 가져올 수 있게 됩니다. 스팀 아이디는 개요에서 말한 대로 Online Subsystem Steam을 활용했다면 PlayerState의 PlayerName에 잘 적용이 되어 있을 겁니다.

    반응형

    댓글

Designed by Tistory.