UNet Tutorial (2) - 간단한 개념


유니티에서 사용되는 개념들


1. 서버와 호스트


Unity 네트워크 시스템에서 게임은 한 개의 서버와 여러 개의 클라이언트를 가지게 된다. 이러한 방식은 클라이언트는 입력만 받고 서버에 전송해주고, 입력을 전송받은 서버가 모든 게임의 계산 처리를 한 이후 클라이언트에 전송해주는 데디케이트(Dedicate) 서버 방식에 사용된다. 전용 서버가 없는 P2P 방식의 경우에는 클라이언트 중 하나가 서버의 역할을 맡게 되며, 이 클라이언트는 “호스트”라고 부른다.



호스트는 동일 프로세스에서 서버이자 클라이언트이다. 호스트는 LocalClient라는 특수 클라이언트 유형을 사용하며, 다른 클라이언트는 RemoteClient를 사용한다. LocalClient는 동일 프로세스에 위치하고 있으므로 직접 함수 호출과 메시지 대기열을 통해 로컬 서버와 통신을 한다. RemoteClient는 서버와 일반적인 네트워크 연결을 통해 데이터를 주고 받는다.

네트워크 시스템의 목표 중 하나는 LocalClients와 RemoteClients 코드를 동일하게 하여 개발자가 되도록이면 한 종류의 클라이언트만 고려해도 되도록 하는 것이다.





2. 인스턴스화와 스폰


Unity에서는 GameObject.Instantiate() 함수를 통해서 새로운 Unity 게임 오브젝트를 생성한다. 하지만 네트워크 시스템의 경우 오브젝트는 NetworkServer를 통해서 “스폰”되어야만 네트워크에서 활성화가 된다. 이 과정은 서버에서만 할 수 있으며, 이를 통해 오브젝트가 연결된 클라이언트에서도 생성되도록 할 수 있다. 오브젝트가 스폰된 이후에는 스폰 시스템이 배포된 오브젝트의 생명주기 관리와 상태 동기화 원칙을 사용한다.



3. 플레이어, 로컬 플레이어, 권한


네트워크 시스템에서 플레이어 오브젝트는 특수하게 취급된다. 게임 플레이어 각각에 연관된 플레이어 오브젝트에 커맨드가 보내지게 된다. 자신이 아닌 다른 사람의 플레이어 오브젝트에는 커맨드를 호출할 수 없다. 플레이어가 추가되고 관계가 연결된 경우, 해당 플레이어 오브젝트는 플레이어 클라이언트의 “로컬 플레이어” 오브젝트가 된다. isLocalPlayer 프로퍼티는 true로 설정되며, 클라이언트 오브젝트에 호출된 OnStartLocalPlayer() 콜백이 발생한다. 아래 다이어그램은 두 클라이언트와 해당 로컬 플레이어의 예제를 보여준다.



오직 “본인” 플레이어 오브젝트에만 isLocalPlayer 플래그가 설정된다. 이 플래그를 통해 입력 프로세싱 필터링, 카메라 위치 조작, 또는 특정 플레이어에 대해서만 변경되어야 하는 클라이언트측 동작을 처리할 수 있다.

플레이어 오브젝트는 isLocalPlayer와 더불어 “로컬 권한”을 가질 수도 있다. 이는 소유자 클라이언트의 플레이어 오브젝트가 해당 오브젝트에 대한 권한이 있다는 의미입니다. 권한은 대부분 움직임을 제어하는 데 주로 활용되지만, 다른 용도로도 사용할 수 있습니다. NetworkTransform 컴포넌트는 이 권한을 이해하며 설정된 경우 클라이언트에서의 움직임을 보냅니다. NetworkIdentity는 LocalPlayerAuthority를 설정할 수 있는 체크박스가 있다.

적 오브젝트와 같이 비플레이어 오브젝트는 연관 클라이언트가 없으므로, 서버가 권한을 가지게 된다.



NetworkBehaviour에 있는 “hasAuthority” 프로퍼티를 사용하여 오브젝트에 권한이 있는지 파악할 수 있다. 따라서 비플레이어 오브젝트는 서버에 권한이 있고, 플레이어 오브젝트 중 localPlayerAuthority가 설정된 것은 각 소유자 클라이언트에 권한이 있다.





4. 비플레이어 오브젝트의 클라이언트 권한


Unity 5.2 릴리스 버전부터 클라이언트는 비플레이어 오브젝트에 권한을 가질 수 있으며, 두 가지 방법이 있다. 하나는 NetworkServer.SpawnWithClientAuthority로 오브젝트를 스폰한 후 클라이언트 네트워크 연결에 전달하여 소유권을 이전하는 방법이고 다른 하나는 NetworkIdentity.AssignClientAuthority를 클라이언트 네트워크 연결과 사용하여 소유권을 이전하는 방법이다.

클라이언트에 권한을 할당하면 오브젝트 NetworkBehaviours에 OnStartAuthority()가 호출되며, hasAuthority 프로퍼티는 true가 된다. 다른 클라이언트의 hasAuthority 프로퍼티는 계속 false가 된다. 클라이언트 권한이 있는 비플레이어 오브젝트는 플레이어와 같이 커맨드를 보낼 수 있다. 이 커맨드는 오브젝트 서버 인스턴스에서 실행되지, 연결에 관련된 플레이어 서버에서 실행되지 않는다.

클라이언트 권한이 있는 비플레이어 오브젝트는 NetworkIdentity에서 LocalPlayerAuthority가 체크되어 있어야 한다.

아래는 오브젝트를 스폰하고 스폰한 플레이어 클라이언트의 권한을 할당하는 예시이다.


[Command]
void CmdSpawn()
{
    var go = (GameObject)Instantiate(otherPrefab, transform.position + new Vector3(0,1,0), Quaternion.identity);
    NetworkServer.SpawnWithClientAuthority(go, connectionToClient);
}





5. 네트워크 컨텍스트 프로퍼티


NetworkBehaviour 클래스에는 언제든 네트워크된 오브젝트의 네트워크 컨텍스트가 무엇인지 알 수 있게 하는 프로퍼티가 있다.

  • isServer - 오브젝트가 스폰되었고 서버나 호스트에 있는 경우 true다.
  • isClient - 오브젝트가 서버에 의해 생성되었고 클라이언트에 있는 경우 true다.
  • isLocalPlayer - 오브젝트가 해당 클라이언트 플레이어 오브젝트인 경우 true다.
  • hasAuthority - 로컬 프로세스가 이 오브젝트를 소유하는 경우 true다.

이들 프로퍼티는 에디터 인스펙터 창의 오브젝트 미리보기 창을 통해 확인할 수 있다.

반응형

+ Recent posts