This document is about: FUSION 2
SWITCH TO

상호 작용

상호 작용

상호 작용에는 KCC에 어떤 방식으로든 영향을 미치는 객체를 탐지, 등록, 등록 해제 및 업데이트하는 것이 포함됩니다.

KCC는 두 가지 인터랙션 타입을 지원합니다:

  • 충돌
    • 물리학 기반 상호작용.
    • KCC가 씬 객체(일반 충돌기 또는 트리거일 수 있음)와 충돌을 시작/중지할 때 트리거 됩니다.
  • 수정자
    • KCC.AddModifier()KCC.RemoveModifier()를 통해 수동으로 상호작용을 등록합니다.
    • 충돌하는 게임 객체는 씬 객체 또는 프리팹일 수 있습니다.

어느 경우든 충돌하는 게임 객체는 다음과 같은 요건을 충족해야 합니다:

  • NetworkObject 컴포넌트가 있어야 합니다.
  • IKCCInteractionProvider 또는 파생 인터페이스를 구현하는 컴포넌트가 있어야 합니다.

인터페이스 IKCCInteractionProvider는 두 가지 중요한 메소드를 선언합니다:

bool CanStartInteraction() => true;

  • 상호작용의 시작을 제어합니다.
  • 특정 조건이 충족될 때까지 상호작용을 연기할 수 있습니다(True가 반환될 때까지 KCC 내에 등록되지 않음)
  • 예를 들어 플레이어가 영역에 들어가서 완전한 상태에서만 속도 버프를 받을 때

bool CanStopInteraction() => true;

  • 상호작용의 끝을 제어합니다
  • 상호작용 중지는 특정 조건이 충족될 때까지 연기될 수 있습니다(True가 반환될 때까지 KCC에 등록됩니다)
  • 예를 들어 플레이어가 영역에 진입하여 속도가 느려지면 플레이어가 완전히 건강해질 때까지 제거가 지연됩니다(플레이어가 영역 내에 여전히 있는지 여부에 관계없이)

일반적으로 상호작용은 KCC 프로세서를 제공하여 사용자 지정 이동 로직을 주입하지만, 이에 국한되지는 않습니다. KCC와 상호작용하는 객체는 게임 플레이 코드에서 반복할 수도 있습니다.

중력이 증가한 월드존(박스 콜라이더 - 트리거로 정의됨)을 만들어 보겠습니다. 이 게임 객체는 KCC 계산에서 중력을 조정하는 특수한 GravityProcessor를 가지고 있습니다. 이 컴포넌트는 현재 위치의 이름을 제공하는 IUIMapProvider 인터페이스를 구현합니다. UI 스크립트는 화면의 텍스트를 업데이트하기 위해 다음 코드를 실행합니다:

C#

public void Update()
{
    foreach (IUIMapProvider mapProvider in _kcc.GetInteractions<IUIMapProvider>())
    {
        // Set location name in UI to first location provided by KCC.
        _location.text = mapProvider.LocationName;
        break;
    }
}

일반적으로 이러한 반복은 KCC 물리 쿼리의 결과를 재사용하기 때문에 매우 효율적입니다.

프로세서

프로세서는 KCC와 상호작용하는 특수한 물체입니다(상호작용은 KCC에 프로세서를 제공합니다). 기본 로직 위에 다양한 움직임 효과를 깔끔하게 혼합할 수 있도록 설계되었습니다.

메인 진입 점

IKCCProcessor

  • 모든 프로세서를 위한 기본 인터페이스.
  • 진입/종료 콜백 및 업데이트 메소드를 실행하는 데 사용됩니다.
  • IKCCProcessor를 구현하는 스크립트는 KCC 설정의 프로세서에 연결할 수 있습니다.
  • IKCCProcessor가 선언한 메소드의 실행은 다음과 같이 지원됩니다
    • ✅ 프리팹
    • Runner.Spawn()으로 생성된 인스턴스
    • GameObject.Instantiate()로 생성된 인스턴스

C#

public partial interface IKCCProcessor
{
    float GetPriority(KCC kcc) => default;       // Processors with higher priority are executed first.

    void OnEnter(KCC kcc, KCCData data)       {} // Called when a KCC starts interacting with the processor.
    void OnExit(KCC kcc, KCCData data)        {} // Called when a KCC stops interacting with the processor.
    void OnStay(KCC kcc, KCCData data)        {} // Called when a KCC interacts with the processor and the movement is fully predicted or extrapolated.
    void OnInterpolate(KCC kcc, KCCData data) {} // Called when a KCC interacts with the processor and the movement is interpolated.
}

IKCCProcessorProvider

  • IKCCInteractionProvider에서 파생
  • IKCCProcessor의 인스턴스를 제공하는 모든 상호작용을 위한 기본 인터페이스

기본 프로세스 타입


C#

public abstract partial class KCCProcessor : MonoBehaviour, IKCCProcessor, IKCCProcessorProvider
  • NetworkObject 컴포넌트 필요
  • ✅ KCC 설정에서 Processors로 직접 연결할 수 있습니다.
  • [Networked] 속성 미지원

C#

public abstract partial class NetworkKCCProcessor : NetworkBehaviour, IKCCProcessor, IKCCProcessorProvider
  • NetworkObject 컴포넌트 필요
  • ✅ KCC 설정에서 Processors로 직접 연결할 수 있습니다.
  • ✅ 스폰된 객체의 [Networked] 속성 지원

C#

public abstract partial class NetworkTRSPProcessor : NetworkTRSP, IKCCProcessor, IKCCProcessorProvider
  • NetworkObject 컴포넌트 필요
  • ✅ KCC 설정에서 Processors로 직접 연결할 수 있습니다.
  • ✅ 스폰된 객체의 [Networked] 속성 지원
  • ✅ 사용자 지정 트랜스폼 동기화 기능을 갖춘 관심 영역의 위치 제공자(고급)

C#

public abstract partial class ScriptableKCCProcessor : ScriptableObject, IKCCProcessor
  • ScriptableObject의 모든 혜택
  • ✅ KCC 설정에서 Processors로 직접 연결할 수 있습니다.
  • [Networked] 속성 미지원
  • ❗ 실행 시 IKCCProcessorProvider 인스턴스를 통해 KCC에 프로세서를 추가해야 합니다

일반적인 사용 방법

KCC 프로세서가 사용되는 일반적인 패턴은 다음과 같습니다:

  1. 일반 로직이 포함된 상태 비저장 프로세서(예: 환경 프로세서).
  2. 스테이트 풀 프로세서가 씬에서 생성됩니다(예: 손상 영역).
  3. 각 플레이어에 대해 하위 객체(예: 제트팩)로 스테이트 풀 프로세서가 생성됩니다.

실행

다음 그림은 복수의 KCC 프로세서의 실행 순서에 대한 예시입니다. 일부 단계는 단순화를 위해 생략합니다.

복수 KCC 프로세서의 실행 순서.
  1. KCC는 모든 프로세서를 캐시하고 스냅샷으로 백업합니다.
  2. 프로세서 목록은 스냅샷으로 다시 재설정되고 모든 단계의 시작에서 우선순위에 따라 정렬됩니다. 한 단계에서 프로세서를 억제하는 것은 다른 단계에서의 실행에 영향을 미치지 않습니다.
  3. IPrepareData 단계가 실행되며, 이 경우 환경 프로세서에 의해 구현되며, 기본값은 KCCData.KinematicSpeed로 설정됩니다.
  4. 환경 프로세서는 KCC.ExecuteStage<ISetKinematicSpeed>()를 호출하여 맞춤형 ISetKinematicSpeed 단계를 실행합니다. 이 단계는 KCCData.KinematicSpeed 속성을 계산하기 위한 것으로 머드 프로세서스프린트 프로세서에 의해 구현됩니다.
  5. 머드 프로세서에서 먼저 Execute(ISetKinematicSpeed)를 실행합니다. KCCData.KinematicSpeed에 50%를 곱하여(머드에서 느린 속도를 시뮬레이션), KCC.SuppressProcessors<IKCCProcessor>()를 호출하여 다른 프로세서의 실행을 억제합니다.
  6. 스프린트 프로세서가 억제되고 Execute(ISetKinematicSpeed)는 실행되지 않습니다.
  7. KCC는 KCC Data의 속성을 기반으로 위치 델타를 계산하여 이동합니다.

다른 프로세서 억제

  • 보류 중인 프로세서의 실행은 활성화 단계에서 억제할 수 있습니다
  • KCC.SuppressProcessors(IKCCProcessor processor) - 특정 프로세서 인스턴스를 억제합니다
  • KCC.SuppressProcessors<T>() - T 타입의 모든 프로세서를 억제합니다. 인터페이스를 사용하여 프로세서를 논리적으로 그룹으로 분할하는 것이 유효한 접근 방식입니다
  • 활성 단계 없이 이 메소드를 호출하면 예외가 발생합니다

후처리

  • KCC, 단계 후처리를 지원합니다 - 활성 스테이지 종료 시 메소드 실행
  • 우선순위가 낮은 프로세서(예: KCCData에서 최종 값을 클램핑하는 것)를 대체하는 매우 가벼운 메소드입니다
  • KCC.EnqueuePostProcess(Action<KCC, KCCData> callback)
  • 활성 단계 없이 이 메소드를 호출하면 예외가 발생합니다

단계

단계는 프로세서에서 실행되는 특정 메소드 호출의 시퀀스입니다. IKCCStage<T> 인터페이스에서 파생된 유형(통상 인터페이스)에 의해 고유하게 식별됩니다.

단계의 동작 방식

  1. KCC.ExecuteStage<T>()를 호출하여 스테이지를 실행합니다. 여기서 T는 스테이지 타입입니다.
  2. T를 구현하는 모든 프로세서는 임시 리스트에 캐싱 되고 우선순위 프로세서별로 상위에서 하위로 정렬됩니다.
  3. 메서드 T.Execute(T stage, KCC kcc, KCCData data)는 목록의 모든 프로세서에서 순차적으로 실행됩니다.
  4. 현재 실행 중인 프로세서는 KCC.SuppressProcessor(IKCCProcessor processor) / KCC.SuppressProcessors<T>()로 호출하여 보류 중인 프로세서를 스테이지 실행에서 억제할 수 있으며, 이들 프로세서는 임시 목록에서 제거되어 사실상 실행을 건너뛸 수 있습니다.
  5. 이미 실행된 프로세서 또는 보류 중인 프로세서 목록을 쿼리 할 수 있습니다.

스테이지 메소드와 기본 프로세서 콜백을 비교하기 위해 - OnStay / OnInterpolate는 고정/렌더 업데이트마다 한 번씩 추적되는 모든 프로세서에서 실행이 보장되며 실행을 억제할 수 없습니다.

일반적으로 스테이지는 언제든지 실행할 수 있으며, 다른 스테이지 내에서 스테이지를 실행하여 실행을 중첩시킬 수도 있습니다.

⚠️ 프로세서를 억제하는 것은 항상 현재 실행 중인 단계의 맥락에 있습니다.

내장 스테이지 타입

KCC는 고정/렌더 업데이트 중에 실행되는 다음 단계를 지원합니다:

  • IBeginMove - 완전히 예측된 또는 외삽된 움직임의 시작 시에 실행됩니다. KCC를 구성하고, 기능을 활성화/비활성화하고, 힘을 추가 등에 사용됩니다.
  • IPrepareData - 위치 델타를 계산하기 전에 실행됩니다. 이 스테이지는 보류 중인 델타 시간이 전체 예측을 실행하는 외삽 임곗값 보다 클 경우에만 실행됩니다. 이 스테이지는 일반적으로 속도를 계산하기 위해 사용자 정의 스테이지 계층 구조를 실행하기에 가장 좋은 장소입니다.
  • IAfterMoveStep - 각 이동 단계(물리 쿼리 + 콜라이더로부터의 침투 제거) 후 충돌 히트 및 OnEnter()/OnExit() 콜백을 업데이트하기 전에 실행됩니다. 사소한 위치 보정, 벡터 프로젝션 등에 사용됩니다. 이 단계는 전체 예측(보류 중인 델타 시간이 외삽 임곗값보다 큼)을 실행하는 경우에만 실행됩니다. 이 방법은 KCC가 너무 빨리 움직이면 여러 번 연속 호출될 수 있습니다(CCD 적용).
  • IEndMove - 완전히 예측된 또는 외삽된 움직임의 끝에서 실행됩니다. 후처리를 적용하는 데 사용합니다.

단계 예제

  1. 사용자 지정 정의

C#

public interface ICustomStage : IKCCStage<ICustomStage>
{
}
  1. 사용자 지정 단계 구현

C#

public class ExampleProcessor : KCCProcessor, ICustomStage
{
    public void Execute(ICustomStage stage, KCC kcc, KCCData data)
    {
        // Implementation of the custom stage.
    }
}
  1. 사용자 지정 단계 실행

C#

public override void FixedUpdateNetwork()
{
    _kcc.ExecuteStage<ICustomStage>();
}
  1. 환경 프로세서의 사용자 정의 단계의 실제 예.

C#

public interface ISetGravity            : IKCCStage<ISetGravity>            {} // Dedicated stage to set KCCData.Gravity property.
public interface ISetDynamicVelocity    : IKCCStage<ISetDynamicVelocity>    {} // Dedicated stage to set KCCData.DynamicVelocity property.
public interface ISetKinematicDirection : IKCCStage<ISetKinematicDirection> {} // Dedicated stage to set KCCData.KinematicDirection property.
public interface ISetKinematicTangent   : IKCCStage<ISetKinematicTangent>   {} // Dedicated stage to set KCCData.KinematicTangent property.
public interface ISetKinematicSpeed     : IKCCStage<ISetKinematicSpeed>     {} // Dedicated stage to set KCCData.KinematicSpeed property.
public interface ISetKinematicVelocity  : IKCCStage<ISetKinematicVelocity>  {} // Dedicated stage to set KCCData.KinematicVelocity property.

public partial class EnvironmentProcessor : KCCProcessor, IPrepareData
{
    // IPrepareData INTERFACE

    public virtual void Execute(PrepareData stage, KCC kcc, KCCData data)
    {
        // Execute custom set of stages defined above.
        kcc.ExecuteStage<ISetGravity>();
        kcc.ExecuteStage<ISetDynamicVelocity>();
        kcc.ExecuteStage<ISetKinematicDirection>();
        kcc.ExecuteStage<ISetKinematicTangent>();
        kcc.ExecuteStage<ISetKinematicSpeed>();
        kcc.ExecuteStage<ISetKinematicVelocity>();

        // Suppress other processors for this stage.
        SuppressOtherEnvironmentProcessors(kcc);
    }
}

프로세서의 실행 순서는 런타임 시에도 검사가 가능하며, 자세한 내용은 실행 정보를 확인하시기 바랍니다.

스테이지 객체

스테이지는 이동 로직에 국한되지 않으며, 특별한 스테이지 객체를 통과하여 다른 게임 플레이 메커니즘에 사용하는 것이 가능합니다.

  1. 스테이지의 정의.

C#

public interface IDamageBoost : IKCCStage<DamageBoost> {}
  1. 스테이지 객체의 정의.

C#

public sealed class DamageBoost : IDamageBoost
{
    public float MaxValue { get; private set; }

    public void Execute(DamageBoost stage, KCC kcc, KCCData data) {}

    public void ProcessDamageBoost(float damageBoost)
    {
        MaxValue = Mathf.Max(MaxValue, damageBoost);
    }

    public void Reset()
    {
        MaxValue = default;
    }
}
  1. 프로세서에서 IDamageBoost 스테이지 구현.

C#

public class DamageBoostArea : KCCProcessor, IDamageBoost
{
    public float DamageBoost = 4.0f;

    public void Execute(DamageBoost stage, KCC kcc, KCCData data)
    {
        stage.ProcessDamageBoost(DamageBoost);
    }
}
  1. 스테이지 객체의 실행.

C#

public class Player : NetworkBehaviour
{
    public KCC KCC;

    // The stage is used like a player "attribute".
    private DamageBoost _damageBoost = new DamageBoost();

    public override void FixedUpdateNetwork()
    {
        _damageBoost.Reset();

        KCC.ExecuteStage(_damageBoost);

        float damageMultiplier = _damageBoost.MaxValue;

        // Firing from weapon...
        // The damage multiplier can be combined with base projectile damage.
    }
}

스테이지 객체는 IBeforeStageIAfterStage 인터페이스를 구현할 수도 있습니다.

C#

public sealed class CustomStageObject : ICustomStage, IBeforeStage, IAfterStage
{
    public void Execute(CustomStageObject stage, KCC kcc, KCCData data)
    {
    }

    // IBeforeStage is optional and executed on stage objects only.
    // It is typically used to reset members to default values before stage is executed.
    void IBeforeStage.BeforeStage(KCC kcc, KCCData data)
    {
    }

    // IAfterStage is optional and executed on stage objects only.
    // It is typically used to iterate over collected information and calculate results on the end of the stage.
    void IAfterStage.AfterStage(KCC kcc, KCCData data)
    {
    }
}

실행 순서

  1. 스테이지 객체의 IBeforeStage.BeforeStage()
  2. 우선순위별로 분류된 모든 프로세서의 IKCCStage<T>.Execute(T stage, KCC kcc, KCCData data)
  3. 스테이지 오브젝트의 IKCCStage<T>.Execute(T stage, KCC kcc, KCCData data)
  4. KCC.EnqueuePostProcess()로 대기열에 있는 모든 후처리를 실행
  5. 스테이지 객체의 IAfterStage.AfterStage()

실행 정보에서도 스테이지 실행 순서를 확인하실 수 있으며, 자세한 내용은 실행 정보를 확인하시기 바랍니다.

Back to top