네트워크 객체
개요
NetworkObject
컴포넌트는 네트워크를 통해 공유할 수 있도록 네트워크 ID를 GameObject
에 할당합니다. 모든 플레이어가 볼 수 있고 씬의 역동적인 부분인 게임 객체에는 NetworkObject
스크립트가 포함되어야 합니다.
Fusion은 NetworkObject
에서 사용자 지정 네트워크 동작을 생성하기 위한 두 가지 클래스를 제공합니다.
- 시뮬레이션 관련 동작을 위한
SimulationBehaviour
클래스 NetworkBehaviour
클래스는[Networked]
상태를 유지하거나 추적
NetworkObject
GameObject
의 루트 노드에 있는 단일 NetworkObject
스크립트 하나면 전체 계층을 제어하기에 충분합니다. 런타임에 NetworkObject
는 계층에서 모든 SimulationBehaviour
와 NetworkBehaviour
들을 찾습니다.
필요한 경우 NetworkObject
를 중첩할 수 있습니다. 이 경우 NetworkObject
는 중첩된 하위 항목을 검색하지 않고 하위 항목인 SimulationBehaviour
와 NetworkBehaviour
들을 추적합니다. 일반적인 사용 사례는 드라이버가 섀시의 방향(이동)을 제어하고 터렛이 포탑(사격)을 제어하는 섀시와 포탑으로 구성된 2인용 제어 탱크입니다.
프리팹 / 객체 테이블
Prefab
파라미터가 Fusion에 적합하도록 하려면(그리고 모든 클라이언트가 어떤 프리팹인지 정확히 동의하는지 확인하려면) 프리팹 자체가 Fusion에 등록되어야 합니다. 정상적인 상황에서는 Fusion 툴 세트가 이러한 프리팹을 자동으로 탐지하고 등록하지만, 유니티 인스펙터에서 NetworkProjectConfig
를 선택하고 Rebuild Object Table
을 눌러 수동으로 탐지를 트리거할 수도 있습니다.
인스턴스화 / 스폰
NetworkObject
프리팹의 인스턴스화에는 두 단계가 필요합니다.
- 디자인 타임: 클라이언트가
NetworkObject
프리팹 ID에 동의하는 동일한NetworkProjectConfig
에셋을 가지고 있어야 합니다. 이 작업은NetworkProjectConfig
에셋에서Rebuild Object Table
을 실행하여 수행합니다. - 실행 시:
NetworkObject
프리팹을 매개 변수로 사용하여NetworkRunner
에서Spawn()
을 호출합니다.
중요: 일반적인 유니티 Instantiate()
메소드를 호출하면 손상된 로컬 인스턴스가 생성됩니다!
파괴 / 스폰 해제
NetworkObject
를 제거하려면 Runner.Despawn()
를 호출하고 객체를 매개 변수로 전달합니다. 이렇게 하면 객체와 중첩된 모든 객체가 삭제됩니다. 맨 위 개체만 제거하려면 중첩된 개체를 먼저 수동으로 분리해야 합니다.
NetworkObject 찾기
NetworkObject
는 NetworkObject
를 나타내는 NetworkId
를 전달하여 NetworkRunner.TryFindObject()
를 사용하여 찾을 수 있습니다.
NetworkId
와 NetworkObject
들은 [Networked]
속성을 사용하여 네트워크에 연결할 수 있지만, NetworkObject
를 네트워킹 하면 게임 상태에 NetworkId
만 추가됩니다(실제 NetworkObject
의 데이터는 버퍼에 다시 복사되지 않고 참조만 합니다).
[Networked] NetworkObject
에 접근할 때 NetworkRunner.TryFindObject()
는 사전에 실행되므로 개발자가 ID를 네트워크로 연결하여 수동으로 실행하거나 객체 자체를 실행하는 것이 좋습니다.
상태 권한
상태 권한은 누가 [Networked]
속성의 올바른 값을 변경하고 결정할 권리가 있는지를 나타냅니다.
개념 자체는 Fusion의 모든 토폴로지에서 동일하지만 기능적인 차이가 있습니다.
서버 모드 및 호스팅 모드
ServerMode
및 HostMode
에서 서버/호스트의 시뮬레이션은 단일 상태 권한입니다. 따라서 if문장을 사용하여 코드 경로의 캡슐화가 가능합니다. Object.HasStateAuthority
. Object.HasStateAuthority
는 서버/호스트에서 true만 리턴합니다.
서버/클라이언트 모드에서 이 값은 항상 PlayerRef.None
이 됩니다. 서버/호스트 피어가 항상 상태 권한 역할을 하기 때문입니다.
공유 모드
SharedMode
에서 상태 권한은 플레이어 간에 공유됩니다. 모든 플레이어는 시뮬레이션의 특정 객체 수에 대한 상태 권한을 가질 수 있습니다. 따라서 Object.HasStateAuthority
는 권한을 가진 플레이어에게 true로 리턴됩니다. Photon Shared 서버는 NetworkObjects
의 상태 권한을 관리 하지만 해당 객체에 대한 상태 권한은 가지고 있지 않습니다.
상태 권한은 어떤 PlayerRef
의 피어가 NetworkObject
의 상태(네트워크 된 속성)에 대한 최종 권한인지를 나타내며, 해당 네트워크 속성 값은 다른 클라이언트에 틱 스냅샷으로 복제됩니다.
노트: StateAuthority
속성은 공유 모드에서만 적용 가능합니다.
공유 모드에서 NetworkObject
의 상태 권한이 변경될 수 있지만, 주어진 객체를 가진 플레이어는 항상 한 명뿐입니다. 여러 플레이어가 동일한 객체에 대한 상태 권한을 가질 수 없습니다!
DestroyWhenStateAuthorityLeaves
:StateAuthority
를 가진 플레이어가 게임을 떠날 때, 이NetworkObject
가 자동으로 디스폰 되는지를 나타냅니다.AllowStateAuthorityOverride
: 다른 플레이어가 이미 상태 권한을 가지고 있을 때 플레이어가 상태 권한을 획득할 수 있는지 여부를 나타냅니다. 주의: 이 속성은 생성 후에는 변경할 수 없으므로 생성 전에 설정해야 합니다. 대부분의 경우AllowStateAuthorityOverride
를 그대로 둡니다.ReleaseStateAuthority()
: 현재의 상태 권한 객체에 대한 제어를 해제합니다.RequestStateAuthority()
: 클라이언트에서PlayerRef
를NetworkObject
에 대한 상태 권한으로 할당하도록 호출할 수 있습니다. Photon 공유 서버는 다음과 같은 경우에만 요청을 허용합니다.- 객체가 사용 가능한
AllowStateAuthorityOverride
를 가지고 있거나 - 객체가 현재 상태 권한이 없습니다. 이것은 상태 권한자가 게임 세션을 떠났거나 이전에
ReleaseStateAuthority()
호출에 의해 통제를 포기했기 때문일 수 있습니다.
- 객체가 사용 가능한
StateAuthorityChanged()
: 객체에 대한 상태 권한이 변경될 때IStateAuthorityChanged
인터페이스의 구현을 호출합니다.
입력 권한
InputAuthority
속성은 이 NetworkObject
의 FixedUpdateNetwork
에서 GetInput()
이 호출될 때 리턴되는 PlayerRef
의 입력 데이터(INetworkInput
)를 나타냅니다. 플레이어 입력은 입력 권한이 있는 클라이언트와 입력 권한에서만 사용할 수 있습니다. GetInput()
이 호출되면 다른 모든 클라이언트(Proxies)가 false를 반환합니다.
입력 권한 및 Fusion의 INetworkInput
처리는 클라이언트 예측 및 재시뮬레이션의 기본이기 때문에 주로 ServerMode
와 HostMode
를 위한 것입니다. 그러나 SharedMode
에서는 사용자 입력이 상태 권한에 의해 즉시 소비되므로 INetworkStruct
입력 시스템은 필수적이지 않습니다. Fusion 입력 시스템을 편의상 SharedMode
에서 사용하는 것이 바람직할 수도 있고 향후에 ServerMode
또는 HostMode
로 전환할 수 있는 가능성을 열어두는 것이 바람직할 수 있으며 나중에 리팩터링 하는 것을 피합니다.
HasInputAuthority
:Runner.LocalPlayer == Object.InputAuthority
이면true
를 반환합니다. 스크립트에서 이를 사용하여NetworkRunner.LocalPlayer
가 이NetworkObject
에 대하여 입력 권한 여부를 테스트합니다.AssignInputAuthority()
: 메소드에 전달된PlayerRef
에 입력 권한을 할당합니다. 객체의 상태 권한에서만 변경할 수 있습니다.RemoveInputAuthority()
:NetworkObject
에서 입력 권한을PlayerRef.None
으로 설정하여 제거합니다. 객체의 상태 권한자만 변경할 수 있습니다.