네트워크 객체
컴포넌트 개요
네트워크 객체는 NetworkObject
컴포넌트를 가진 GameObject
로, 방(Room) 내 단일 네트워크 엔티티를 나타냅니다.
네트워크 객체는 스폰 하거나 씬 객체로 로드하여 생성할 수 있습니다.
NetworkId
서버는 NetworkObject
컴포넌트에 NetworkId
값을 할당합니다.
이 값은 룸 내에서 객체를 고유하게 식별하는 정수입니다.
NetworkId
는 모든 피어 간에 동일하며 네트워크에서 객체를 참조하는 데 사용됩니다.
로컬 네트워크 객체 인스턴스는 NetworkRunner.TryFindObject()
를 호출하여 이 NetworkId
로 찾을 수 있습니다.
네트워크 객체 스폰
네트워크 객체는 다음 두 가지 방법으로 생성됩니다:
Runner.Spawn()
호출
Spawn
이 호출되면,NetworkObject
컴포넌트를 포함하는GameObject
가 생성되고, 스폰 작업이 네트워크에서 복제됩니다.
Runner.StartGame()
에 전달된INetworkObjectProvider
는 스폰 된 객체가 생성되는 방법(예: 프리팹 인스턴스화, 기존 객체 복제, 코드로 새 객체 생성, 풀에서 객체 가져오기)을 정의합니다.- 네트워크 객체가 포함된 씬 로드
씬 관리 참조
두 메소드 모두 객체를 생성하며, 네트워크 객체와 해당 상태를 관심 있는 피어들에게 복제합니다.
Runner.Spawn()
으로 네트워크 객체 생성
Runner.Spawn()
은 호스트 모드에서 서버에서만 호출할 수 있으며, 공유 모드에서는 생성된 객체의 상태 권한을 가질 클라이언트에서 호출할 수 있습니다.
호출되면 지정된 프리팹이 인스턴스화되고, 해당 NetworkObject
컴포넌트가 NetworkRunner
에 연결됩니다.
스폰 된 객체는 관심 있는 다른 클라이언트들에게 복제됩니다.
프리팹 / 객체 테이블
네트워크 객체를 스폰할 때 일반적으로 프리팹 인스턴스가 전달되며, 이는 인스턴스화에 사용됩니다.
Fusion이 해당 프리팹을 이해하고 모든 클라이언트가 동일한 프리팹에 동의하도록 하기 위해, 프리팹은 Fusion에 등록되어야 합니다.
일반적으로 Fusion 도구는 이러한 프리팹을 자동으로 감지하고 등록하지만, 유니티 인스펙터에서 NetworkProjectConfig를 선택하고 "Rebuild Object Table"을 눌러 이 감지를 수동으로 트리거 할 수도 있습니다.
런타임에 NetworkBehaviour
추가/제거
네트워크 객체가 스폰 된 후에는 NetworkBehaviour
를 추가하거나 제거할 수 없습니다.
그러나 스폰 이전에는 런타임에 추가/제거가 가능합니다. 이 경우 몇 가지 고려 사항이 있습니다:
NetworkObject
는 미리 준비되어야 합니다.- 사용자 정의 네트워크 객체 생성은 일반적으로 사용자 정의
INetworkObjectProvider
구현으로 처리됩니다.
씬 네트워크 객체 로드 (Loading Scene Network Objects)
씬과 함께 네트워크 객체를 로드하는 것은 객체를 생성하고 연결하는 또 다른 방법입니다.
ISceneManager
인스턴스를 사용하여 씬을 로드하면(씬 관리 참조) 씬 내 활성화된 네트워크 객체가 마스터 클라이언트 또는 서버 모드에서 서버에 연결됩니다.
그 후 각 씬 객체에 할당된 NetworkId
가 다른 모든 클라이언트에게 전달되고, 클라이언트들은 해당 NetworkId
값을 사용하여 씬 객체를 연결합니다.
연결
네트워크 객체가 스폰 되거나 씬과 함께 로드되면, 객체가 연결됩니다.
연결 과정에서는 네트워크 객체에 NetworkId
를 할당하고, 해당 NetworkBehaviour
컴포넌트의 네트워크 속성을 위한 메모리를 할당하며, 관련된 모든 NetworkBehaviour
를 초기화합니다.
연결이 완료되면, NetworkObject
는 모든 자식 NetworkBehaviour
에서 Spawned()
를 호출합니다.
이후 객체는 유효한 것으로 간주되며, 네트워크 속성과 RPC 메서드를 사용할 수 있습니다.
관련된 이벤트 메서드(FixedUpdateNetwork()
및 Render()
등)와 인터페이스 호출이 시작됩니다.
상태 권한
연결된 모든 네트워크 객체에는 명시적 또는 암시적 상태 권한이 있으며, 이는 PlayerRef
로 지정됩니다.
Runner.StateAuthority
값이 PlayerRef.None
인 경우, 서버 피어가 암시적 상태 권한을 가집니다.
서버 모드 (호스트/전용/단일)
Runner.StateAuthority
는 항상 PlayerRef.None
이며, 서버가 항상 상태 권한을 가집니다. 상태 권한은 변경할 수 없습니다.
공유 서버 모드
NetworkObject.StateAuthority
는 항상 유효한 PlayerRef
입니다. 상태 권한은 특정 제한 사항 내에서 변경될 수 있습니다:
- 상태 권한은 할당할 수 없습니다. 플레이어는 자신이 현재 상태 권한을 가지고 있더라도 다른 플레이어에게 상태 권한을 할당할 수 없습니다.
- 상태 권한은 획득할 수 있습니다. 플레이어는
Object.RequestStateAuthority()
를 호출하여 권한을 요청할 수 있습니다.
RequestStateAuthority()
는 다음 조건 중 하나를 만족해야 성공합니다:
NetworkObject.AllowStateAuthorityOverride
가 true로 설정된 경우.- 이전 상태 권한 소유자가
Object.ReleaseStateAuthority()
를 호출한 경우.
상태 권한 변경을 감지하려면 IStateAuthorityChanged
인터페이스를 사용할 수 있습니다.
OnStateAuthorityChanged
는 객체의 StateAuthority
가 변경될 때 모든 클라이언트에서 호출됩니다.
{% if Fusion_v2 %}
입력 권한
입력 권한은 서버 모드(호스트, 전용, 단일)에만 해당되며, 공유 서버 모드에서는 적용되지 않습니다.
입력 권한은 GetInput()
이 호출될 때 이 객체에 대해 어떤 플레이어의 입력이 반환되어야 하는지를 나타냅니다.
복제
객체가 연결된 후, 네트워크 객체는 각 틱마다 시뮬레이션되며, 상태 권한은 그 결과 상태를 다른 모든 피어에게 복제합니다.
중요: 네트워크 속성은 상태 권한에서 다른 피어로만 복제됩니다. 다른 피어에서 네트워크 속성을 변경하면, 다음 상태 권한 상태가 도달할 때 덮어씌워집니다.
입력 권한의 경우, 이는 예측의 정상적인 부분으로, 수신된 서버 상태보다 먼저 시뮬레이션을 진행하고, 새로운 서버 상태가 도달할 때마다 롤백 하여 다시 시뮬레이션을 진행합니다.
관심 관리
네트워크 객체가 어떤 플레이어에게 복제되는지는 다양한 관심 관리 메커니즘을 사용하여 필터링할 수 있습니다. 예를 들어, 관심 영역 등이 있습니다.
관심 관리는 특정 플레이어에게 객체 업데이트를 제외하는 방식으로 데이터를 줄이는 메커니즘이며, 많은 네트워크 객체와/또는 높은 플레이어 수를 가진 게임에서 매우 중요합니다.
관심 관리에 대해 자세히 알아보기
중첩
Fusion은 네트워크 객체의 중첩을 지원합니다. 중첩은 하나의 네트워크 게임 객체가 다른 객체의 자식으로 계층에 위치하는 것을 의미합니다.
씬 객체와 스폰 된 프리팹은 하나의 GameObject 프리팹에서 여러 개의 네트워크 객체가 될 수 있습니다.
객체가 연결되면, 각 네트워크 객체는 부모 및 자식 네트워크 객체와는 별개의 엔티티로 취급됩니다.
네트워크 행동은 가장 직접적인 부모와 연결되며, 루트 네트워크 객체는 중첩된 자식 네트워크 객체에 속한 네트워크 동작을 연결하지 않습니다.