수정중인 페이지 입니다.

네트워크 객체

소개

NetworkObject는 네트워크 전체에서 공유할 수 있도록 GameObject에 네트워크 ID를 할당합니다. 모든 플레이어가 볼 수 있고 씬의 역동적인 부분인 GameObject에는 NetworkObject 스크립트를 포함해야 합니다.

Fusion은 사용자 지정 네트워크 행동을 위해 파생할 수 있도록 한 2개의 NetworkObject 기반 클래스로 제공합니다:

  • 시뮬레이션에 관련된 행동을 위한 SimulationBehaviour
  • [Networked] 상태 보관 또는 추적을 위한 NetworkBehaviour.

메인 화면으로

NetworkObject

GameObject의 루트 노드에 있는 하나의 NetworkObject 스크립트만으로도 전체 계층을 제어하기에 충분합니다. 런타임에 NetworkObject는 해당 계층에서 모든 SimulationBehaviourNetworkBehaviour를 찾습니다.

필요한 경우 NetworkObject는 중첩할 수 있습니다. 이 경우 NetworkObject는 중첩된 하위 항목을 검색하지 않고 하위 네트워크 객체가 그 아래에 있는 모든 SimulationBehaviourNetworkBehaviour를 추적하도록 합니다. 일반적인 사용 사례는 2명의 플레이어가 차대와 포탑으로 만들어진 탱크를 제어하고, 드라이버가 차대의 방향을 제어(이동)하고 포병이 포탑을 제어(발사)합니다.

메인 화면으로

프리팹 / 객체 테이블

Prefab 파라미터가 Fusion에 적합하려면(그리고 모든 클라이언트가 정확히 어떤 프리팹인지 동의하도록 하려면) 프리팹 자체를 Fusion에 등록해야 합니다. 정상적인 상황에서는 Fusion 도구 집합이 이러한 프리팹을 자동으로 감지하여 등록하지만, 유니티 인스펙터에서 NetworkProjectConfig를 선택하고 Rebuild Object Table을 눌러 수동으로 이 탐지를 트리거 할 수도 있습니다.

메인 화면으로

인스턴스화 / 스폰

NetworkObject 프리팹을 인스턴스화하려면 두 가지 단계가 필요합니다:

  1. 편집 시: 클라이언트가 NetworkObject 프리팹 ID에 일치하는 동일한 NetworkProjectConfig 에셋을 가져야 합니다. 이 작업은 NetworkProjectConfig 에셋에서 Rebuild Object Table을 실행하여 수행합니다. 그리고,
  2. 실행 시: NetworkRunner에서 파라미터로 NetworkObject을 전달하여 Spawn()을 호출합니다.

중요: 유니티의 일반 Instantiate() 메소드를 호출하면 깨진 로컬 인스턴스만 생성됩니다!

메인 화면으로

파괴 / 스폰 해제

NetworkObject를 파괴하려면 파라미터로 객체를 전달하여 Runner.Despawn() 호출합니다. 이렇게 하면 중첩된 개체뿐만 아니라 모든 중첩된 개체도 파괴됩니다. 상위 개체만 디스패닝하려면 먼저 중첩된 개체의 상위 항목을 수동으로 해제해야 합니다.

메인 화면으로

권한

NetworkObject는 2개의 권한 타입이 있습니다(소유권으로 알려짐):

  • 입력 권한 그리고,
  • 상태 권한.

메인 화면으로

입력 Vs 상태

입력 권한을 사용하면 해당 객체에 대한 사용자 입력을 수집하고 보낼 수 있습니다. 또한 클라이언트가 FixedUpdateNetwork()에서 동일한 입력을 획득하여 객체의 미래 상태를 시뮬레이션하고 로컬로 예측할 수 있습니다. 상태 권한에서는 입력을 기반으로 상태를 읽고 시뮬레이션할 수 있으므로 예측과 실제 상태가 동일한 코드에 의해 변형될 수 있습니다.

즉, 상태 권한은 개체 상태에 대한 최종 제어를 제공하고 동기화를 위해 다른 모든 클라이언트로 전송되는 델타 스냅샷에 대한 내용을 직접 지시합니다. 결국, 클라이언트가 상태 권한으로 설정한 상태는 입력 권한을 가진 클라이언트가 예측한 모든 것을 대체합니다.

메인 화면으로

권한 할당

게임 코드는 HasInputAuthorityHasStateAuthority 속성을 통해 주어진 NetworkObject에 대한 클라이언트의 권한 유형을 확인할 수 있습니다.

NetworkObjectRunner.Spawn()로 스폰 될 때, 호출 클라이언트가 자신 또는 다른 클라이언트에 입력 권한을 할당할 수 있습니다.

  • 네트워크 모드가 클라이언트 권한으로 설정된 경우 클라이언트는 객체에 대한 상태 권한도 인수할 수 있습니다.
  • 네트워크 모드가 전용 서버 또는 클라이언트 호스트로 설정된 경우, 상태 권한이 항상 할당됩니다.

메인 화면으로

SimulationBehaviour

모든 SimulationBehaviourObject 속성을 통해 관련된 NetworkObject에 접근할 수 있습니다.

시뮬레이션 은 네트워크 상태를 업데이트하는 Fusion의 방법입니다. 시뮬레이션 상태에 속하거나 영향을 미치는 모든 행동은 MonoBehaviour가 아닌 SimulationBehaviour에서 파생되어야 합니다.

예를 들어 탱크 샘플의 LevelManager는 파워업을 생성합니다. 비록 파워업이 NetworkObject이지만, LevelManager는 동작을 실행시키기 위해 시뮬레이션 상태를 알고 있습니다. 따라서 SimulationBehaviour를 상속받는 것이 올바른 접근 방식입니다.

public class LevelManager : SimulationBehaviour
{
    [SerializeField] private float _powerupDelay;
    [SerializeField] private NetworkObject _powerupPrefab;

    private TickTimer _powerupTimer;

    public override void FixedUpdateNetwork()
    {
        // All of the level management logic happens server-side, so bail if we're not the server.
        if (!Object.HasStateAuthority) return;

        // Only active duty of the LevelManager is to spawn powerups whenever the timer expires
        if (_powerupTimer.ExpiredOrNotRunning(Runner)) {
            // Reset timer, and check if there is a free spot to spawn a new powerup
            _powerupTimer = TickTimer.CreateFromSeconds(Runner,_powerupDelay);
            SpawnPoint spawnPoint = GetSpawnPoint(SpawnPoint.Type.Powerup);

            if (spawnPoint != null) {
                Debug.Log("Spawning Powerup");
                NetworkObject powerupobj = Runner.Spawn(_powerupPrefab, spawnPoint.transform.position, spawnPoint.transform.rotation, PlayerRef.None);
                powerupobj.GetComponent<Powerup>().Init();
            } else {
                Debug.Log("Not Spawning Powerup - no free spot");
            }
        }
    }    
}

[Networked] 속성에 대한 접근이 필요한 경우 대신 NetworkBehaviour에서 파생되어야 합니다.

메인 화면으로

NetworkBehaviour

NetworkBehaviour는 동일한 노드 또는 부모 노드에 NetworkObject가 필요합니다.

NetworkBehaviour는 동기화 상태를 전달할 수 있는 SimulationBehaviour이므로 연관된 NetworkObject가 있어야 합니다.

메인 화면으로

네트워크 된 상태

내부적으로 Fusion은 현재 로컬 틱의 전체 네트워크 상태를 나타내는 단일 메모리 버퍼를 유지합니다. 상태는 [Networked]로 속성을 표시함으로써 게임 코드에 노출됩니다.

네트워크 상태 값을 정의하고 직렬화하려면 속성 앞에 [Networked] 태그를 추가하십시오. Fusion은 자체 고성능 데이터 버퍼 및 델타 압축을 통해 이 태그로 지정된 속성을 자동으로 처리합니다. 속성 setter 및 getter는 컴파일 시간에 사용자 지정 코드로 대체하여 메모리 할당 오버헤드를 제거하고 최적의 성능을 제공합니다.

public class PlayerBehaviour : NetworkedBehaviour {
  [Networked] public float Health { get; set; }
}

컴파일 시 Fusion은 빈 get/set 스텁을 실제 네트워크 상태 데이터에 접근하는 코드로 바꿉니다. 직접 접근을 통해 메모리 할당 오버헤드를 제거하고 최고의 성능을 제공합니다. 수동으로 구현하지 마세요.

버퍼에 직접 접근한다는 것은 변경이 발생할 때마다 속성이 해당 변경사항을 즉시 반영한다는 의미이기도 합니다.

네트워크 된 상태에 영향을 주는 로직을 작성하기 위해서, FixedUpdateNetwork()를 오버라이드하고 구현합니다.

public override void FixedUpdateNetwork() {
    Health += Runner.DeltaTime * HealthRegen;
}

메인 화면으로

제약사항

[Networked] 속성은 아래의 제약 사항을 준수해야 합니다:

  • 속성에 빈 get/set 쌍이 있어야 합니다.
  • 다음의 타입만 포함할 수 있습니다:
    • 원시 타입 (전체 목록은 아래 참고)
    • Unity 타입 (전체 목록은 아래 참고)
    • INetworkStruct를 구현하고 최상위 레벨에서 정의된 구조체 (클래스에서는 중첩될 수 없음)
    • 네트워크 구조체의 포인터
    • [Capacity] 속성을 사용한 최대 길이를 가진 문자열 (기본값 16)
    • NetworkObject
    • NetworkBehaviour 하위 클래스
    • [Capacity] 속성을 사용하여 최대 길이를 설정한 NetworkArray<T>(기본값 1)
  • 부울 값에 대해서는 bool 대신 NetworkBool 을 사용합니다 - C#의 플랫폼 전반에 걸쳐 일관된 크기의 부울을 적용하지 않기 때문에 NetworkBool을 사용하여 단일 비트로 올바르게 직렬화합니다.

사용할 수 있는 원시 타입:

  • byte, sbyte
  • Int16, Int32, Int64
  • UInt16, UInt32, UInt64
  • float
  • double

사용할 수 있는 유니티 타입:

  • Vector2, Vector3, Vector4
  • Quaternion
  • Matrix4x4
  • BoundingSphere
  • Bounds
  • Rect
  • Color
  • Vector2Int, Vector3Int
  • BoundsInt
  • RectInt
  • Color32

메인 화면으로

속성

[Accuracy] 속성을 사용하여 개별 숫자 유형 속성의 정확도를 제어할 수 있습니다.

public class PlayerBehaviour : NetworkedBehaviour {
  [Networked, Accuracy(0.001)]
  public float Health { get; set; }
}

[Capacity]NetworkArray 및 문자열의 최대 길이를 정의하는 데 사용됩니다. Fusion에서 이러한 유형을 네트워킹 하려면 최대 길이를 설정해야 합니다.

[Capacity(14)] string MyString { get; set; }
[Capacity(8)]  NetworkArray<byte> MyArray { get; }

메인 화면으로

OnChanged에 대한 반응

네트워크 속성이 변경되었을 때 게임 코드가 Fusion에 의해 트리거 될 수 있습니다. 유효 코드를 작성하려면 [Networked] 속성에 (OnChanged) 파라미터를 사용하세요.

public class Powerup : NetworkBehaviour{
    [Networked(OnChanged = nameof(OnTypeChanged))] public Type type { get; set; }

    // Has to be public static void
    public static void OnTypeChanged(Changed<Powerup> changed){
        changed.Behaviour.OnTypeChanged();
    }

    private void OnTypeChanged(){
        // Some logic reacting to the value change of the "type" property
    }
}

콜백 이름을 지정하는 것 외에도 어떤 시스템에서 콜백이 실행되는지를 제어할 수 있습니다.

  • OnChangedLocal (기본값 false): true로 설정 also 는 속성을 변경한 시스템에서 이벤트 후크가 호출됩니다.

  • OnChangedRemote (기본값 true): false로 설정 only 는 속성을 변경한 시스템에서 이벤트 훅을 호출

메인 화면으로

오버라이드 할 수 있는 메소드

NetworkObject에는 여러 가지 라이프 사이클별의 메소드가, 이 모든 메소드들은 SimulationBehaviourNetworkBehaviour를 구현할 때 오버라이드될 수 있습니다.

함수 설명
FixedUpdateNetwork() 퓨전의 고정된 타입 스텝 콜백. 핵심 게임 로직에 사용.
Spawned() 스폰 콜백 사후.
Despawned(bool hasState) 네트워크 객체가 디스폰되기전에 호출.
---
bool hasState: 행동의 상태가 아직 접근할 수 있으면.
Render() 시뮬레이션 프레임 렌더링 콜백 이후. 모든 시뮬레이션이 완료된 후 실행됩니다. Fusion이 물리를 처리할 때 유니티의 Update 대신 사용.

메인 화면으로

FixedUpdateNetwork

FixedUpdateNetwork() - 줄여서 FUN()-은 한 틱에서 다음 틱까지 새 상태를 시뮬레이션할 때 호출됩니다. 고정된 간격으로 FixedUpdateNetwork()가 호출됩니다. 이 간격의 시간 단계는 Simulation > Tick Rate 아래의 NetworkProjectConfig 에셋에 정의됩니다. 시간 단계는 Runner.DeltaTime 속성을 통해 모든 SimulationBehaviourNetworkBehaviour에서 접근할 수 있습니다.

동일한 상태 전환에 대해 FixedUpdateNetwork()를 여러 번 호출하여 서버에서 받은 업데이트(실측 자료)를 기반으로 현재 예측 상태를 다시 시뮬레이션할 수 있습니다. Fusion이 재 시뮬레이션을 위해 FixedUpdateNetwork()를 호출하기 전에 네트워크 상태를 재설정하므로 재 시뮬레이션[Networked] 속성에 대해 투명합니다.

중요: 일반적인 로컬 비네트워크 상태 변수(예: 클래스 멤버)는 재설정되지 않으며 추가적인 전달 상태 진행으로 간주합니다.

기술문서 TOP으로 돌아가기