멀티플레이어 게임은 네트워크 가시성 개념을 사용하여 게임플레이 동안 특정 시점에 플레이어에게 표시할 게임 오브젝트를 결정합니다. 움직이는 시점과 움직이는 게임 오브젝트가 포함된 게임에서는 일반적으로 플레이어가 게임 내 모든 요소를 한 번에 볼 수 없습니다.
특정 플레이어가 게임플레이 동안 특정 시점에 게임 내 대부분의 다른 플레이어, 논플레이어 캐릭터(NPC) 또는 기타 이동하거나 상호작용하는 오브젝트를 볼 수 없는 경우 호스트는 이러한 요소에 대한 정보를 플레이어의 클라이언트에 보낼 필요가 없습니다.
이러한 방식에는 두 가지 이점이 있습니다.
네트워크에서 플레이어 간 전송되는 데이터 크기가 감소하므로 게임의 응답성을 향상하고 대역폭 사용량을 줄일 수 있습니다. 크고 복잡한 멀티플레이어 게임일수록 이러한 문제가 더욱 중요합니다.
또한 해킹 방지에도 도움이 됩니다. 볼 수 없는 오브젝트에 대한 정보가 플레이어 클라이언트에 없기 때문에 해당 플레이어의 컴퓨터를 해킹해도 해당 정보가 표시되지 않습니다.
네트워킹 컨텍스트에서 “가시성”은 반드시 화면에 직접적으로 표시되는 게임 오브젝트만을 의미하지 않습니다. 그보다는 문제가 되는 게임 오브젝트에 대한 데이터를 특정 클라이언트에 보낼지 여부와 더 관련이 있습니다. 간단히 말하면, 클라이언트가 게임 오브젝트를 ‘인식할’ 수 없으면 네트워크에서 해당 게임 오브젝트에 대한 정보를 보내지 않아도 됩니다. 네트워크에서 필요한 데이터만 보내도록 전송량을 제한하는 것이 가장 이상적입니다. 네트워크상으로 불필요한 데이터를 대용량으로 전송하면 네트워크 성능이 저하될 수 있습니다.
하지만 게임 오브젝트가 특정 플레이어에게 실제로 보이는지 확인하는 작업은 복잡하며 많은 인력과 비용이 소모되기도 합니다. 따라서 플레이어가 네트워크로 연결된 데이터를 받았는지, 즉 데이터가 ’네트워크에서 표시(Network Visible)’되는지 확인할 수 있는 더욱 간단한 계산 방식을 사용하는 것이 좋습니다. 적절한 균형을 이루기 위해서는 가시성 결정을 위한 복잡도 계산 비용과 네트워크상으로 필요 이상의 정보를 전송하는 데 드는 비용을 잘 고려해야 합니다. 이를 계산하기 위한 아주 간단한 방법은 거리(근접도) 검사이며, Unity는 이 작업을 위한 빌트인 컴포넌트를 제공합니다.
Unity Network Proximity Checker 컴포넌트를 사용하면 플레이어에 대한 네트워크 가시성을 아주 간편하게 구현할 수 있습니다. 이 컴포넌트는 물리 시스템과 연동하여 게임 오브젝트가 충분히 가까이 있는지, 즉 멀티플레이어 게임에서 네트워크 메시지를 전송하기 위한 목적으로 “표시”되는지 확인합니다.
이 컴포넌트를 사용하려면 네트워크 가시성을 제한할 네트워크로 연결된 게임 오브젝트의 프리팹에 컴포넌트를 추가하십시오.
네트워크 근접성 검사기에는 다음과 같은 두 가지 설정 가능한 가시성 파라미터가 들어 있습니다.
Vis Range는 네트워크가 플레이어에게 게임 오브젝트를 표시할 때 고려해야 할 거리 임계값을 제어합니다.
Vis Update Interval은 거리 테스트의 수행 빈도를 제어합니다. 이 값은 검사 간의 지연 시간(단위: 초)입니다. 이 값을 사용하면 가능한 적은 수의 테스트를 사용하도록 검사를 최적화할 수 있습니다. 숫자가 낮을 수록 업데이트가 더 자주 발생합니다. 느리게 움직이는 게임 오브젝트는 이 간격을 높은 값으로 설정하고, 빠르게 움직이는 게임 오브젝트는 낮은 값으로 설정하십시오.
네트워크 근접성 검사기에서 사용할 게임 오브젝트에 Collider 컴포넌트를 연결해야 합니다.
원격 클라이언트의 플레이어가 네트워크에 연결된 게임에 참가하면 네트워크상에서 해당 플레이어에게 표시되는 게임 오브젝트만 원격 클라이언트에서 스폰됩니다. 즉, 플레이어가 네트워크로 연결된 다수의 게임 오브젝트가 존재하는 대규모 월드에 진입하더라도 해당 월드에 배치된 모든 게임 오브젝트를 표시하지 않아도 되기 때문에 게임을 빠르게 시작할 수 있습니다. 단, 이는 씬에 있는 네트워크로 연결된 게임 오브젝트에만 적용되며 에셋 로딩에는 영향을 주지 않습니다. 등록된 프리팹과 씬 게임 오브젝트를 위한 에셋을 로드하는 데는 여전히 일정 시간이 소요됩니다.
월드에서 플레이어가 이동하면 네트워크에 표시되는 게임 오브젝트 세트가 바뀝니다. 플레이어의 클라이언트는 이와 같은 변경이 발생할 때마다 이에 대한 정보를 받습니다. 게임 오브젝트가 네트워크에 더 이상 표시되지 않으면 ObjectHide** **메시지가 클라이언트에 전송됩니다. 기본적으로 Unity는 이 메시지를 수신할 때 해당 게임 오브젝트를 삭제합니다. 게임 오브젝트가 표시되면, Unity가 해당 게임 오브젝트를 처음으로 스폰한 것처럼 클라이언트는 ObjectSpawn 메시지를 받습니다. 기본적으로 해당 게임 오브젝트는 스폰된 다른 게임 오브젝트처럼 인스턴스화됩니다.
호스트는 게임을 호스팅하는 플레이어에 대해 서버와 클라이언트 역할을 동시에 수행하기 때문에 서버와 동일한 씬을 공유합니다. 이런 이유로 로컬 플레이어에게 표시되지 않는 게임 오브젝트는 삭제할 수 없습니다.
대신에 호출되는 NetworkBehaviour 클래스의 OnSetLocalVisibility** **가상 메서드가 제공됩니다. 이 메서드는 호스트의 가시성 상태를 변경하는 게임 오브젝트의 모든 NetworkBehaviour
스크립트에서 호출됩니다.
OnSetLocalVisibility
의 기본 구현에서는 게임 오브젝트에서 모든 Renderer 컴포넌트를 비활성화하거나 활성화합니다. 이러한 구현을 커스터마이즈하려는 경우 스크립트에서 해당 메서드를 오버라이드하고, 게임 오브젝트가 네트워크에 표시되거나 표시되지 않을 때(예: HUD 요소 또는 렌더러 비활성화) 호스트 및 로컬 클라이언트의 응답 방식에 대한 새로운 동작을 제공할 수 있습니다.