This document is about: FUSION 2
SWITCH TO

유니티 물리 애드온

개요

Rigidbody 및 Rigidbody2D 컴포넌트의 클라이언트 예측 및 동기화에 필요한 컴포넌트를 포함합니다.

  • NetworkRigidbody3D - Rigidbody 상태를 상태 권한에서 다른 피어로 동기화합니다.
  • NetworkRigidbody2D - Rigidbody2D 상태를 상태 권한에서 다른 피어로 동기화합니다.
  • RunnerPhysicsSimulate3D - 물리 시뮬레이션을 처리하는 NetworkRunner GameObject에 필요한 컴포넌트.
  • RunnerPhysicsSimulate2D - Physics2D 시뮬레이션을 처리하는 NetworkRunner GameObject에 필요한 컴포넌트.

사용법

Network Rigidbody 컴포넌트를 사용하려면 다음 단계를 따릅니다:

  1. Rigidbody 프리팹 또는 씬 객체에 NetworkRigidbody3D(또는 2D의 NetworkRigidbody2D)와 NetworkObject를 추가합니다. 이 컴포넌트는 상태 권한에서 다른 피어로 rigidbody 상태를 복제합니다. 또한 클라이언트 예측 재시뮬레이션을 위한 rigidbody의 리셋 및 조정을 처리합니다.
  2. NetworkRunner 프리팹에 RunnerSimulatePhysics3D(또는 해당하는 경우 2D)를 추가합니다. 이 컴포넌트는 유니티의 Physics.Simulate() 호출을 대신합니다.
  3. FixedUpdateNetwork() 내부에서 모든 시뮬레이션/컨트롤러 코드가 실행되는지 확인합니다.

다운로드

현재 메인 Fusion SDK에는 유니티 물리 애드온이 포함되어 있습니다. 향후 변경될 수 있으며 다운로드 링크는 여기에 제공됩니다.

Fusion 1에서 Fusion 2로의 마이그레이션

  • IBeforePhysicsStepIAfterPhysicsStep은 삭제되었으며, RunnerSimulatePhysics에서 콜백으로 대체할 수 있습니다. 아래 콜백을 참조하십시오.

애드온 업데이트

새 패키지를 가져오기 전에 애드온 루트 폴더(Assets > Photon > FusionAddons > Physics)를 삭제하는 것이 좋습니다.

확장 / 변경

NetworkRigidbodyRunnerSimulatePhysics의 컴포넌트는 대부분의 사용 사례에 적합하도록 설계되었습니다. 그러나 이러한 컴포넌트는 자신의 프로젝트별 요구 사항에 맞게 수정할 수 있습니다. 이러한 클래스의 일부 멤버들은 가상이므로 무시할 수 있습니다. 그러나 대부분의 경우 이러한 컴포넌트를 가이드로 사용하여 자체 클래스를 만들거나 직접 수정할 수 있습니다. Fusion 코어의 내부 멤버들은 이러한 컴포넌트에 의존하지 않으므로(일부 샘플 및 데모에서는 사용할 수 있지만) 적합한 대로 수정할 수 있습니다.

NetworkRigidbody2D / NetworkRigidbody3D

NetworkRigidbody3DNetworkRigidbody2DNetworkTRSP 클래스에서 상속되었고, 이 클래스의 모든 AOI 처리를 상속받습니다. 관심 지역 지정에 대해서는 이 지침서의 NetworkTRSP 섹션을 확인해 주세요.

축척 동기화

활성화하면 transform.localScale이 동기화됩니다.

부모 동기화

활성화된 경우 transform.parent가 동기화됩니다. 부모 Rigidbody가 있는 Rigidbody는 Kinematic으로 설정해야 합니다. 부모 Rigidbody는 객체 AreaOfInterest를 부모 네트워크 객체로 자동 설정합니다.

몇 가지 주의 사항이 있습니다:

  • 부모 변환에는 반드시 NetworkBehaviour 컴포넌트가 있어야 합니다. 이렇게 하면 NetworkBehaviourId를 사용하여 부모를 찾을 수 있습니다.
  • NetworkRigidbody는 네트워크 개체의 루트에 있어야 합니다(일반적으로 이 경우에 해당됩니다).
  • 부모 트랜스폼은 네트워크 개체의 자식 변환일 수 있습니다. 예를 들어 플레이어의 손입니다.

보간 대상

Render() 동안 보간을 위해 이동되는 변환입니다. 이 변환은 일반적으로 콜라이더를 포함하지 않는 Rigidbody의 하위 변환입니다.

Null인 경우, 네트워크 Rigidbody의 루트는 보간을 위해 이동되고 시뮬레이션 루프가 시작될 때 틱 정확한 위치로 돌아갑니다. 코드를 통해 InterpolationTarget 값은 런타임 시에 변경될 수 있습니다.

루트가 아닌 보간 대상을 사용하면 보간이 객체에 대한 물리적 캐싱을 중단하지 않는다는 이점이 있습니다. 그러나 이렇게 하면 동기 스케일이 모든 하위 Rigidbody에 대해 무효가 됩니다.

보간 대상을 null로 유지하는 것이 좋습니다. 마찰/적층과 관련하여 일부 원치 않는 강체 동작이 발생하는 경우에만 이를 사용하여 탐색할 것을 권장합니다.

보간 대상이 필요한 경우:

  • _MovePosition()을 사용하여 운동학적 Rigidbody를 이동합니다. 보간을 사용하지 않고 대상 보간은 transform.position과 회전을 설정합니다. 이와 같이 변환을 직접 변경하는 것은 변환이 수정된 후에 이루어지더라도 RB에 대한 모든 MovePosition() 호출을 무시합니다.
  • 물리는 보간에 영향을 받지 않아야 합니다. 변환을 직접 이동하여 보간할 경우 강체의 정마찰이 깨지고 잠이 드는 등의 부작용이 있습니다. Sleep Thresholds 렌더링 는 이를 완화하지만 간섭을 허용할 수 없는 경우가 있을 수 있습니다.

보간 대상을 사용하는 경우 콜라이더가 포함되어 있지 않은지 확인하십시오. 왜냐하면 콜라이더를 이동하면 강체가 더러워지기 때문입니다(보간 대상을 사용하여 피하고자 하는 것입니다). 모든 외관 효과는 이 보간 대상의 일부여야 합니다.

노트: 스케일과 Parenting를 모두 사용하는 경우 보간 대상을 사용하면 올바른 결과를 얻을 수 없습니다. GameObject 스케일은 코드를 통해 복제하기 거의 불가능한 상위 스케일의 영향을 받기 때문에 정확한 스케일 결과를 얻으려면 InterpolationTarget을 null로 두는 것이 좋습니다.

노트: 일반적인 실수는 카메라가 보간 대상을 따르지 않는 것입니다. 카메라가 보간 대상을 따르도록 하는 것이 중요합니다.

슬립 임계값

이 옵션을 사용하면 현재 트랜스폼 상태의 변경 사항이 표시된 임곗값을 모두 밑돌면 루트 트랜스폼의 보간이 수행되지 않습니다. 이를 통해 물리적 캐싱이 끊어지고 슬립이 방지되는 루트 트랜스폼 이동 효과가 완화됩니다. 슬립을 허용하는 것은 서버 권한 인스턴스에서 특히 중요한데, 이는 매우 약하게 움직일 때도 네트워크 트래픽이 발생하기 때문입니다. 강체가 슬립을 허용하면 네트워크 트래픽이 크게 줄어듭니다.

참고: Sleep Thresholds(수면 임곗값)만 보간 대상이 사용되지 않는 경우에만 적용할 수 있습니다.

렌더 슬립 임계값 사용

임계값 검사를 활성화합니다. 비활성화된 경우 객체는 항상 보간 됩니다.

렌더 임계값

  • Use Energy - 로컬 강체의 속도 및 각속도의 에너지 레벨이 슬립 임계치 이상인지를 시험하고, 이상이면 보간합니다.
  • Position: 보간이 이 값보다 큰 현재 변환 상태로 위치 변경을 발생시키는 경우 보간이 발생합니다. 0 값은 테스트에서 위치를 제외합니다.
  • Rotation: 보간이 이 값보다 큰 현재 변환 상태로 회전 각도 변경을 발생시키는 경우 보간이 발생합니다. 0의 값은 테스트에서 회전을 제외합니다.
  • Scale: 보간이 이 값보다 큰 현재 변환 상태로 로컬 스케일 변경을 발생시키는 경우 보간이 발생합니다. 0의 값은 테스트에서 스케일을 제외합니다.

Teleport()

NetworkTransform.Teleport를 참고하세요.

MovingTeleport()

이동하는 텔레포트를 시작합니다. 이 메소드는 RunnerSimulatePhysics3DRunnerSimulatePhysics2D가 모의 물리를 갖기 전에 FixedUpdateNetwork()에서 호출되어야 합니다. 이 텔레포트는 물리가 시뮬레이션된 후까지 연기되며 시뮬레이션 테스트 전후의 위치와 회전 값을 모두 캡처합니다. 이를 통해 텔레포트에 이르는 보간이 유효한 사전 텔레포트 TO 타깃을 가질 수 있습니다. 이는 기본 Teleport()의 대안으로, 한 번의 틱 동안 보간이 동결됩니다.

RunnerPhysicsSimulate2D / RunnerPhysicsSimulate3D

컴포넌트를 NetworkRunner 프리팹에 추가해야 하며 유니티에서 AutoSyncTransform과 AutoSimulate를 비활성화합니다. 모든 FixedUpdateNetwork() 컴포넌트는 적용할 수 있는 물리 Simulate()를 호출합니다.

포워드 만

활성화(기본적으로 비활성화)된 경우 해당 물리 Simulate()는 재시뮬레이션 틱을 호출하지 않습니다. 기본적으로 비활성화해야 합니다.

콜백

INetworkRunnerCallbacks.IBeforePhysicsStep 그리고 INetworkRunnerCallbacks.IAfterPhysicsStep은 Fusion 2에서 제거되었으며, 다음 사항으로 교체되었습니다.

OnBeforeSimulate / OnAfterSimulate

등록이 되면 이 메소드는 RunnerSimulatePhysics이 시뮬레이션할 때마다 호출됩니다.

C#

using Fusion;
using Fusion.Addons.Physics;
using UnityEngine;

public class FusionPhysicsAddonExample : NetworkBehaviour 
{
  private RunnerSimulatePhysics3D _physicsSimulator;
  
  public override void Spawned() 
  {
    // Get our RunnerSimulatorPhysics instance (this needs to be added to the Runner)
    _physicsSimulator = Runner.GetComponent<RunnerSimulatePhysics3D>();
    
    // Register callback for EVERY simulation tick
    _physicsSimulator.OnBeforeSimulate += OnBeforeEverySimulate;
  }
  
  public override void Despawned(NetworkRunner runner, bool hasState) 
  {
    // Unregister (a good practice)
    _physicsSimulator.OnBeforeSimulate -= OnBeforeEverySimulate;     
  }
  
  void OnBeforeEverySimulate() { 
    // Implement code to execute before every Physics.Simulate
  }
}

QueueBeforeSimulationCallback / QueueAfterSimulationCallback

이러한 콜백은 다음번에 시뮬레이션이 발생할 때 트리거할 일회성 콜백을 큐에 넣습니다.

C#

using Fusion;
using Fusion.Addons.Physics;
using UnityEngine;

public class FusionPhysicsAddonExample : NetworkBehaviour 
{
  private RunnerSimulatePhysics3D _physicsSimulator;
  
  public override void Spawned() 
  {
    // Get our RunnerSimulatorPhysics instance (this needs to be added to the Runner)
    _physicsSimulator = Runner.GetComponent<RunnerSimulatePhysics3D>
  }

  public override void FixedUpdateNetwork() 
  {
    if (_physicsSimulator.HasSimulatedThisTick) 
    {
      Debug.LogWarning($"Component is running FixedUpdateNetwork AFTER Physics Simulation, check my Script Exec Order");
      PostSimulateActivity();
    } else {
      // Queue our method for a one time deferred callback
      _physicsSimulator.QueueAfterSimulationCallback(PostSimulateActivity);
    }
  }

  void PostSimulateActivity() { 
    // Implement code to execute after specific Physics.Simulate calls
  }
}

알려진 이슈

  • 자식 강체는 물리와 예측할 수 없는 방식으로 상호 작용하며(Kinematic으로 설정된 경우에도) 시뮬레이션 중 강체가 이전 위치에 있는 것처럼 물체와 충돌할 수 있습니다. 따라서 운반된 물체는 충돌에 의존하지 않는 것이 좋으며, 콜라이더는 중첩된 상태에서 비활성화해야 합니다.
  • 네스팅(parenting)을 사용한 스케일은 보간 대상이 없는 모든 부모에 의존합니다. 보간 대상을 사용할 뿐만 아니라 스케일과 네스팅을 결합하려면 보간 대상을 루트에서 분리하고 부모의 보간 대상으로 re-parent 할 수 있는 사용자 지정 처리를 작성해야 합니다. 모든 관련 보간 대상과 함께 강체 콜라이더/계층구조 변환 복사본을 만드는 것입니다.
  • MovePosition() 그리고 MoveRotation은 보간 대상을 사용해야 합니다. 대신 transform.position과 transform.rotation 값을 설정하여 운동학적 강체를 이동시키면 이러한 요구 사항을 직접적으로 피할 수 있습니다.
Back to top