This document is about: PUN 1
SWITCH TO

PUN Classic (v1), PUN 2, Bolt는 휴업 모드입니다. Unity2022에 대해서는 PUN 2에서 서포트하지만, 신기능의 추가는 없습니다. 현재 이용중인 고객님의 PUN 및 Bolt 프로젝트는 중단되지 않고, 퍼포먼스나 성능이 떨어지는 일도 없습니다. 앞으로의 새로운 프로젝트에는 Photon Fusion 또는 Quantum을 사용해 주십시오.

RPG 이동 데모

이 데모는 Photon을 이용한 캐릭터의 기본 이동을 동기화 할 것 입니다. 새로운 PhotonTransformView 컴포넌트는 지점까지 이동할 때 다양한 옵션이 있고 로컬 캐릭터처럼 원격 캐릭터가 부드럽게 이동 하는 것처럼 보여 줍니다.

이 데모에서는 애니메이션 관련된 데이터 전송없이 어떻게 애니메이션이 동기화 되는지를 보여 줍니다. 애니메이터는 이동시에 다양한 변화사항에 대처할 수 있도록 설정되며 이동이 동기화 되기 때문에 올바른 애니메이션이 플레이 되어야 합니다.

screenshot of rpg movement demo
Animated Demo Characters

이 데모의 캐릭터는 "Robot Kyle Mecanim" 프리팹입니다. 이 캐릭터에 사용자 입력을 적용해 주는 PUN의 컴포넌트와 IdleRunJump 스크립트가 있습니다.

Mecanim 데모는 명시적으로 애니메이션 데이터를 전송하는 PhotonAnimatorView 를 이용 합니다.

PhotonTransformView

PhotonTransformView 는 모든 GameObject 에 추가될 수 있으며 PhotonView 를 가지고 있습니다. PhotonTransformView 를 추가한 후 PhotonView 리스트에 있는 "Observed Components" 를 추가 해야 합니다(리스트 아래의 '+' 를 클릭하고 새로운 필드에 PhotonTransformView 를 드래그앤드롭 합니다).

photontransformview as seen in the inspector
일부 옵션을 사용하고 있는 PhotonTransformView.

PhotonTransformView 컴포넌트는 3개의 체크박스가 있으며 위치,회선,스케일을 동기화 가능/불가를 설정 할 수 있습니다. 이러한 것중의 하나를 동기화하는 것으로 설정하면 컴포넌트에는 더 많은 옵션들이 나와 어떻게 데이터를 동기화 하는지 도움을 줄 것 입니다. 이러한 옵션들이 어떤 의미를 가지고 있으며 어떻게 부드러운 네트워크 환경을 생성에 도움을 주는지 상세하게 다루도록 하겠습니다.

위치 동기화

위치는 가장 많이 변경되는 옵션으로 게임에서는 위치 변경이 가장 많이 일어 나기 때문 입니다. 위치 변경(다른것과 동일하게)은 초당 10번 전송되어 집니다. 초당 100 프레임 게임에서는 원격 플레이어가 매 10 프레임마다 업데이트를 받는 다는 의미 입니다. 몇가지 경우에 있어서 갱신은 늦게 도착할 수 있거나 완전히 손실 될 수 있습니다. 여기에는 로컬 캐릭터와 같이 원격-조정되는 객체들의 움직임이 부드러운 휴과를 줄 수 있는 두가지 중요한 개념이 있습니다:

  • Interpolation(보간법): 매 프레임마다 위치를 전송할 수 가 없기 때문에 다른 클라이언트로 부터 수신받은 데이터는 한 지점이고 부드러운 것과는 거리가 있습니다. Interpolation은 개별 변경 정보 사이에서 캐릭터가 부드럽게 움직일 수 있도록 해 줍니다. 원격객체의 최근의 알고 있는 지점으로 부터 이 후 몇 프레임을 통하여 텔레포트처럼 움직이지 않고 부드럽게 이동 하도록 할 수 있습니다.
  • Extrapolation(보외법): Extrapolation 은 동기화된 개릭터가 이전에 수신된 데이터를 기반으로 "현재" 어디에 위치해 있어야 하는지를 평가하려고 하는 것 입니다. 변경사항이 늦거나 손실되었을 때 항상 추측을 통하여 끊어지는 것을 방지할 수 있습니다. 보정이 필요할 수 도 있지만 개발하고 있는 게임유형에 따라서 잘 동작 합니다. 게임의 종류, 다른 inter-와 extrapolation 옵션에 따라 더 잘 동작할 수 있도록 최고로 보이는 것을 항상 시험해야 합니다.

Interpolate 옵션

  • Disabled: Interpolation 을 하지 않습니다. 새로운 위치가 도착할 때 마다 게임오브젝트에 즉시 적용 시킵니다.
  • FixedSpeed: 새로운 위치가 도착할 때 마다 임시변수에 저장하고 캐릭터가 여기로 고정된 스피드를 이용하여 이동 하도록 합니다. 이 것은 동기화된 객체들의 이동 속도를 알고 있을 때 유용한 시나리오로 매우 부드러운 움직임을 보여 줍니다. 만약 실제 속도가 변경되었거나 그곳으로 가는 속도값이 객체가 이동하는 실제 속도와 다르다면 움직임은 점프할 것 입니다.
  • EstimatedSpeed: 다시 캐릭터는 최근 수신된 갱신된 위치로 향해 부드럽게 이동 합니다. 하지만 이 모드에서는 객체들의 속도를 마지막의 위치와 새로운 위치의 차이를 찾아 속도를 계산 합니다. 차와 같은 속도의 변이가 적은 객체들에 최적으로 동작 합니다.
  • SynchronizeValues: 이 모드에서는 원시 객체는 각 업데이트에 실제 속도를 전송하여 interpolation 에서 사용할 수 있도록 합니다. 캐릭터가 갑작스럽게 가속도가 변하는 의지에 따라 왼쪽 오른쪽으로 회전, 점프와 달리기에서 매우 잘 동작 합니다. 이 모드는 속도와 회전 속도도 같이 동기화 되기 때문에 더 많은 데이터를 전송할 것 입니다.게임오브젝트의 스크립트는 속도와 회전 스피드를 런타입시에 변경하고 값을 동기화 하기 위해서 SetSynchronizedValues(Vector3 speed, float turnSpeed) 를 호출 해야 합니다. 이동 스크립트가 움직이는 게임오브젝트의 스피드를 이미 알고 있기 때문에 이 모드가 가장 부드러운 결과를 주게 됩니다.
  • Lerp: MoveTowardsWithFixedSpeed 와 유사하지만 MoveTowards 함수를 사용하는 대신에 Lerp 함수가 사용 됩니다. 동기화된 객체의 러버 밴드 효과안에 결과가 있습니다.

Extrapolate 옵션

Extrapolation 은 객체가 마지막으로 수신된 위치를 기반으로 하여 최근에 수신된 업데이트로 부터 속도아 경과된 시간으로 추측을 하는 것 입니다. 객체의 속도가 빈번하게 변경되지 않을 때 가장 잘 동작 합니다. 수시로 방향을 변경하는 객체에 대해서는 extrapolation 을 사용하지 않아야 합니다. 왜냐하면 잘못된 추측으로 인하여 매우 좋지 않은 지터링을 유발 시킬 수 있기 때문입니다.

  • Disabled: Extrapolation 을 하지 않습니다.
  • SynchronizeValues: 최근 갱신된 것에 원래읜 갱신이 전송된 동기화된 속도와 회전 속도 시간을 곱합니다. 가장 정확한 옵션이지만 더 많은 데이터가 전송 되어야 합니다. 로컬 게임오브젝트에서 SetSynchronizedValues( Vector3 speed, float turnSpeed) 를 호출하여 속도와 회전 속도가 무엇인지 정의 해야 한다는 것을 기억 하세요.
  • EstimatedSpeed: 이 모드에서 속도는 최근의 위치와 이전의 위치의 거리를 계산하여 예측 합니다.
  • FixedSpeed: 고정된 속도를 정의하여 객체 위치를 보외법에 사용 될 수 있도록 허용 합니다.

회전과 스케일 동기화

회전과 스케일은 두개의 interpolation 옵션만 있습니다. 대부분의 게임에서는 객체의 실제 회전과 스케일은 순수하게 미학적인 것으로 게임 플레이에는 전혀 영향을 주지 않습니다. interpolation 옵션은 다음과 같습니다:

  • Disabled: 새로운 값을 수신 했을 때 즉시 객체에 적용 됩니다.
  • RotateTowards/MoveTowards: 객체는 목표 회전/스케일로 천천히 회전/스케일됩니다.
  • Lerp: 객체의 회전/스케일이 목표 값으로 갈 때 Lerp 함수를 이용 합니다.

Mecanim Animator 설정

이 데모는 애니메이션 관련된 데이터의 전송없이 애니메이션을 어떻게 동기화 하는지 보여 줍니다. RPGMovement 클래스는 이 데모에서 이동과 애니메이션 행동을 구현하고 Update() 함수는 다음과 같습니다:

C#

    void Update()
    {
        if( m_PhotonView.isMine == true )
        {
            UpdateRotateMovement();
            UpdateForwardMovement();
            UpdateBackwardMovement();
            UpdateStrafeMovement();
            UpdateGravity();
        }

        UpdateAnimation();
    }

이동은 이 객체가 실제로 플레이어에게 속했을 때만 제어되고 PhotonTransformView 가 네트워크 이동을 제어 합니다. 여전히 원격 객체의 애니메이션을 갱신 합니다. 애니메이터는 설정할 몇개의 파라미터가 있는데 애니메이션 이동에 대한 것은 SpeedDirection 입니다.

캐릭터의 이전 위치와 현재 위치의 차이를 가지고 이동 하는 것을 계산합니다.

C#

    void UpdateAnimation()
    {
        Vector3 movementVector = transform.position - m_LastPosition;

        float speed = Vector3.Dot( movementVector.normalized, transform.forward );
        float direction = Vector3.Dot( movementVector.normalized, transform.right );

        m_Animator.SetFloat( "Speed", speed );
        m_Animator.SetFloat( "Direction", direction );

        m_LastPosition = transform.position;
    }

캐릭터의 포워드 벡터를 이용하여 속도와 방향을 결정 후 애니메이터에게 전달 합니다. 이런 값들이 위치에 기반하여 계산되고 PhotonTransformView로 부터 수신되는 위치 업데이트가 계산에 또한 사용되므로 동기화된 객체들에게 애니메이션이 잘 적용됩니다.

Back to top