This document is about: FUSION 2
SWITCH TO

특징

내장 기능

이러한 기능은 KCC 내부 구현의 일환으로, 기본 상태는 KCCSettings.Features에 의해 정의되며 KCC 인스펙터에서도 설정 가능합니다. 현재 고정/렌더 업데이트를 위한 활성 기능은 'IBeginMove 단계에서 KCC.EnforceFeature()KCC.SuppressFeature()를 호출하여 수정할 수 있습니다.

계속되는 충돌 감지 (CCD)

  • 원하는 속도에 따라 작은 단계로 이동을 나눕니다.
  • 한 걸음으로 이동할 수 있는 최대 거리는 반경의 25~75%이며, KCCSettings.CCDRadiusMultiplier 속성에 의해 제어됩니다.
  • 대부분의 경우 75%가 좋으며, KCC가 기하학적 구조를 실행하는 데 문제가 있는 경우에만 이 값을 낮춥니다.
  • CCDRadiusMultiplier를 낮추기 전에 먼저 KCCSettings.MaxPenetrationSteps(탈침투의 품질 향상)을 늘립니다.
계속되는 충돌 감지
계속되는 충돌 감지.

예측 보정

  • 예측된 위치 오류를 원활하게 수정할 수 있습니다.
  • 예측 오차는 클라이언트와 비교하여 서버상에서 움직임이 다르게 시뮬레이션 될 때 발생하며, 부동소수점 에러 누적, 물리 엔진 상태 차이, 게임 상태에 따른 입력 처리 차이 등 다양한 오류 발생원이 존재합니다…
  • 또 다른 오류 원인은 고정 업데이트와 비교하여 렌더 업데이트 예측과 다른 결과입니다.
  • 이 기능은 시각적/렌더에만 영향을 미치며, 서버에서 수신한 새 상태로 고정 업데이트 스냅의 데이터에 영향을 미칩니다.
  • 이 기능의 적용/억제는 다음 렌더 업데이트를 시작할 때 적용됩니다.
  • 예측 보정 속도는 KCCSettings.PredictionCorrectionSpeed에 의해 제어됩니다.

다음 이미지는 동작 중인 캐릭터의 경로를 고정 업데이트(빨간색), 렌더 업데이트(녹색) 및 예측 수정(노란색)을 보여줍니다:

예측 보정
예측 보정.

안티-지터

  • 지터를 부드럽게 제거하기 위해 렌더 위치 거리 공차를 활성화합니다.
  • 거리는 KCCSettings.AntiJitterDistance(가로축의 경우 X, 세로축의 경우 Y)로 정의됩니다.
  • 값이 높으면 이동 방향 전환 시 현저한 지연이 발생할 수 있으며 캐릭터 비주얼이 지면과 일치하지 않을 수 있습니다(예: 점프 후)

다음 이미지는 KCC와 변환 위치가 XZ 평면의 점으로 표시된 하향식 뷰를 보여줍니다.

안티-지터
안티-지터.
  1. 녹색 점은 KCCData.TargetPosition에 저장된 위치를 나타냅니다. 이는 Transform 컴포넌트에 동기화됩니다.
  2. 파란색 점은 KCCData.TargetPosition에만 저장된 위치를 나타냅니다. 이전 위치의 지터 방지 영역(회색 원) 내에 있기 때문에 Transform 컴포넌트에 동기화되지 않습니다 => 이전(녹색 점) 값을 사용하는 대신.
  3. KCCData.TargetPosition이 현재 안티-지터 영역(빨간색 화살표) 밖으로 이동하면 해당 영역이 해당 지점을 따라 이동하므로 거리 내에서 유지되며 새로운 위치는 Transform으로 동기화됩니다.

프로세서 기능

이러한 기능들은 별도의 구현을 통해 분리하거나 다른 구현으로 교체하기가 매우 쉽습니다.

환경 프로세스

  • KCC 애드온으로 패키지 된 기본 프로세서.
  • 접지 및 플로팅 상태에 대한 동작 정의
  • 지면 접선을 따라 예측 이동
  • 단순한 가속 및 마찰 모델.
  • 사용자 지정 중력.
  • 점프 승수.
  • 원하는 속도를 세밀하게 제어하기 위해 6개의 맞춤형 단계를 실행하는 IPrepareData 단계 구현(일부는 Environment Processor 자체로도 구현):
    • ISetGravity - KCCData.Gravity를 계산하는 전용 스테이지.
    • ISetDynamicVelocity - KCCData.DynamicVelocity를 계산하는 전용 스테이지.
    • ISetKinematicDirection - KCCData.KinematicDirection를 계산하는 전용 스테이지
    • ISetKinematicTangent - KCCData.KinematicTangent를 계산하는 전용 스테이지
    • ISetKinematicSpeed - KCCData.KinematicSpeed를 계산하는 전용 스테이지
    • ISetKinematicVelocity - KCCData.KinematicVelocity를 계산하는 전용 스테이지
  • 각 이동 단계 이후의 특성을 재계산하는 데 사용되는 IAfterMoveStep 단계를 구현합니다(예: 지상의 운동학적 속도 투영).
  • EnvironmentProcessor 프리팹은 Assets\Photon\FusionAddons\KCC\Prefabs에 있습니다.
environment processor
환경 프로세서.

캐릭터의 속도는 이 프로세서에 의해 정의되며, 물, 진흙, 얼음과 같은 다양한 환경에서의 행동을 시뮬레이션하기 위해 씬 객체에 사용될 수 있습니다.

스텝-업 프로세서

  • 계단(일부 높이에서 걸을 수 있는 표면이 있는 수평 이동을 차단하는 지오메트리)을 감지할 수 있습니다.
  • 스텝이 감지되면 KCC는 접지될 때까지 위쪽으로 이동합니다.
  • 최대 스텝 높이는 Step Height로 정의됩니다.
  • 전진 스텝 체크 거리는 Step Depth에 의해 제어됩니다.
  • 위쪽 이동은 적용되지 않은 수평 이동과 동일합니다.
  • 위쪽으로 이동하는 속도에 Step Speed를 곱하여 수평 속도의 손실을 보상합니다.
  • StepUpProcessor 프리팹은 Assets\Photon\FusionAddons\KCC\Prefabs에 있습니다.
스텝-업 프로세서
스텝-업 프로세서.

다음 이미지는 스텝을 감지하는 과정을 보여줍니다:

스텝 업 프로세스
스텝 업 프로세스.
  1. 캐릭터가 가로 방향의 장애물에 의해 막혔을 때 위쪽을 확인합니다.
  2. 캐릭터 앞 공간에 충돌이 없는지 확인하기 위해 앞으로 확인합니다.
  3. 지면이 걸을 수 있는지 감지하기 위한 지면 스냅 점검.
  4. 세 번의 체크가 모두 통과되는 한 캐릭터는 위로 이동합니다.

그라운드 스냅 프로세서

  • 접지와 접촉이 끊겼을 때(계단, 울퉁불퉁한 지형) 접지 상태를 유지할 수 있습니다.
  • 중력이 충분하지 않을 경우 캐릭터를 지면에 더 가깝게 밀어 넣습니다.
  • 최대 스냅 거리는 Snap Distance로 정의됩니다.
  • 지면을 향한 이동속도는 Snap Speed로 정의됩니다.
  • GroundSnapProcessor 프리팹은 Assets\Photon\FusionAddons\KCC\Prefabs에 있습니다.
그라운드 스냅 프로세서
그라운드 스냅 프로세서.

다음 이미지는 그라운드 스냅의 프로세스를 보여줍니다:

그라운드 스냅 프로세스
그라운드 스냅 프로세스.

다음 조건 중 하나가 충족될 때까지 가상적으로 아래로 밀립니다:

  1. 캐릭터는 걸을 수 있는 그라운드에 부딪힙니다=> KCC는 그라운드를 유지하고 그라운드를 향해 이동합니다.
  2. 캐릭터는 걷지 못하는 표면에 부딪혀 미끄러지지 않습니다 => KCC는 접지 상태를 잃음.
  3. Snap Distance 도달 => KCC, 접지상태 상실.

플랫폼 프로세서

  • 플랫폼 객체를 추적하고 위치/회전 변경 사항을 KCC에 전파합니다.
  • 세계 공간과 플랫폼 공간 사이를 통합하여 KCC 프록시를 추적 플랫폼에 스냅 합니다.
  • KCC마다 PlatformProcessor라는 고유한 인스턴스(예를 들어 플레이어 프리팹의 하위 객체)가 있어야 합니다.
  • 세계 공간에서 플랫폼 공간으로의 전환 기간은 PlatformSpaceTransitionDuration으로 정의됩니다.
  • 플랫폼 공간에서 세계 공간으로의 전환 기간은 WorldSpaceTransitionDuration으로 정의됩니다.
  • PlatformProcessor 프리팹은 Assets\Photon\FusionAddons\KCC\Prefabs에 있습니다.
플랫폼 프로세서
플랫폼 프로세서.

일반적인 설정에는 다음과 같은 단계가 필요합니다:

  1. 플레이어/KCC 프리팹 아래의 PlatformProcessor 프리팹을 하위 객체로 드래그 앤 드롭합니다.
  2. KCC 설정에서 프로세서 인스턴스를 Processors 속성에 연결합니다.
  3. 이제 KCC는 모든 플랫폼에서 이동을 추적하고 전파할 수 있게 됩니다.

플랫폼을 올바르게 추적하기 위한 몇 가지 요구 사항과 제약 사항이 있습니다:

  1. 플랫폼 개체에는 NetworkObjectRigidbody(키네마틱) 컴포넌트가 있어야 합니다.
  2. 플랫폼 스크립트는 IPlatform 인터페이스를 구현해야 합니다.
  3. 플랫폼 스크립트는 KCC 프로세서입니다.
  4. 호스트 모드에서는 플랫폼의 이동을 모든(서버 및 클라이언트)에서 예측해야 합니다.
  5. 플랫폼 스크립트의 실행 순서는 PlatformProcessor보다 낮아야 하므로 먼저 실행됩니다.

다음 코드는 플랫폼 스크립트의 예를 보여줍니다:

C#

[DefaultExecutionOrder(-1000)]
[RequireComponent(typeof(Rigidbody))]
public sealed class PlatformMovement : NetworkTRSPProcessor, IPlatform, IBeforeAllTicks
{
    public Transform Transform;
    public Rigidbody Rigidbody;

    public override void Spawned()
    {
        // Enable simulation also for proxy object.
        Runner.SetIsSimulated(Object, true);
    }

    public override void FixedUpdateNetwork()
    {
        CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation);

        // Set network state of NetworkTRSP.
        State.Position = nextPosition;
        State.Rotation = nextRotation;
        
        // Update engine components.
        Transform.position = nextPosition;
        Transform.rotation = nextRotation;
        Rigidbody.position = nextPosition;
    }

    public override void Render()
    {
        CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation);
        
        // Update only engine components, do not store in network state.
        Transform.position = nextPosition;
        Transform.rotation = nextRotation;
        Rigidbody.position = nextPosition;
    }

    void IBeforeAllTicks.BeforeAllTicks(bool resimulation, int tickCount)
    {
        // Restore state of the object before simulation.
        Transform.SetPositionAndRotation(State.Position, State.Rotation);
        Rigidbody.position = State.Position;
    }

    private void CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation)
    {
        nextPosition = State.Position;
        nextRotation = State.Rotation;
        
        // Movement based on waypoints, AnimationClip, ...
    }
}

원활하고 오류 없는 이동전파를 위해서는 실행 순서(IPlatform => PlatformProcessor => Player => KCC)를 준수하는 것이 중요합니다:

  1. 모든 IPlatform 스크립트 업데이트 - 새로운 위치/회전 값을 계산하고 TransformRigidbody 컴포넌트를 업데이트합니다.
  2. 모든 PlatformProcessor 스크립트 업데이트 - 추적된 모든 IPlatform 객체의 처리, KCC TransformKCCData로의 마지막 업데이트 이후 Transform 변경사항 전파. 이 단계를 거치면 모든 플랫폼이 처리되고 캐릭터가 이동합니다.
  3. 모든 Player 스크립트 업데이트 - KCC 이동에 대한 입력값을 설정합니다.
  4. 모든 KCC 스크립트 업데이트 - 움직임 예측 및 보간.

위 프로세스는 어떤 KCC라도 이동하고 최신 플랫폼 및 다른 KCC와 충돌하도록 보장합니다.

⚠️ 플랫폼 예제는 샘플 프로젝트에서 확인하실 수 있습니다.

Back to top