This document is about: QUANTUM 2
SWITCH TO

어빌리티

개요

AbilitiesSystem은 특정 엔티티(일반적으로 액터)와 관련된 사용자 지정 작업을 실행합니다.

기능과 속성

FPS 템플릿에는 어빌리티 구현에 다음과 같은 기능들이 포함되어 있습니다.

  • 모든 어빌리티는 실체입니다.
  • 어빌리티는 켜기/끄기 또는 일회성으로 토글 할 수 있습니다.
  • 어빌리티는 특정 양의 충전 및/또는 충전 타이머가 있습니다.
  • 런타임에 동적으로 기능을 추가하거나 제거할 수 있습니다.
  • 어빌리티의 순차적 실행은 각 어빌리티에 대해 정의된 전체적인 재사용 대기 시간에 의해 제약을 받습니다(0일 수 있음).
  • 여러 어빌리티가 동시에 활성화될 수 있습니다.

기본 어빌리티 구현은 필요에 따라 확장할 수 있으며 기본적으로 다음 속성들이 제공됩니다:

  • Cooldown: 어빌리티 재사용에 필요한 시간
  • Global Cooldown: 사용 후의 전역 어빌리티의 쿨 다운
  • Recharge: 어빌리티 충전하는 경우/할 때의 제어
  • Recharge Time: 1 충전을 얻기 위해 필요한 시간
  • Max Charges: 사용량은 어빌리티의 전체 충전 량에 포함됩니다.
  • Start Charges: 어빌리티가 추가될 때 엔티티에 제공된 초기 충전 양
  • Activation Frame: 어빌리티가 예측/예측 프레임에서 실행되는지 여부의 제어

실행 흐름

어빌리티는 즉각적인 행동이 아닙니다. 처음에는 AbilitiesDesires로 작성되고 나중에 같은 프레임에서 Update에서 실행됩니다. 어빌리티의 수명은 IsFinished 속성에 의해 제어되며, 속성이 true로 설정되면 어빌리티가 비활성화됩니다. 다음 그림은 AbilityController의 API와 실행 흐름을 보여줍니다.

abilities
Abilities.

구현 예제

이 섹션에서는 FPS 템플릿에 포함된 TeleportAbility 구현을 제시하는 AbilitiesSystem의 예를 들어 설명합니다.

C#

public unsafe sealed class TeleportAbilityController : AbilityController {
    //========== PUBLIC MEMBERS ===================================================================================

    public FP                      Distance              = FP._10;
    public FP                      MinimumTravelDistance = FP._1;

    public AssetRefEntityPrototype Effect;
}

TeleportAbility는 기본 속성을 포함하고 몇 가지 특정 속성(예: Distance)이 추가됩니다. 모든 속성은 유니티 인스펙터에서 조정할 수 있습니다.

teleport ability controller
Teleport Ability Controller.

TeleportAbility는 활성화되면 다음과 같은 로직을 실행합니다.

  1. 이 기능은 물리학 라인 캐스트가 전방의 이동 거리를 확인하게 합니다.
  2. Movement 컴포넌트를 가진 어빌리티 소유자인 경우 텔레포트는 이 컴포넌트를 통해 실행되며 그렇지 않으면, Transform3D 컴포넌트에 직적 쓰게 됩니다.
  3. 선택적으로 소유자 엔티티에 효과가 추가됩니다(예: 몇 초 동안의 속도 향상).

C#

internal override bool Activate(Frame frame, EntityRef entity)
{
    EntityRef    ownerRef       = frame.GetOwnerEntity(entity);
    Transform3D* transform3D    = frame.GetComponent<Transform3D>(ownerRef);

    FPVector3    position       = transform3D->Position;
    FPVector3    direction      = transform3D->Forward();

    // 1. Calculate teleport destination

    FPVector3    targetPosition = position + direction * Distance;

    // 2. Visibility check for obstacles - simple linecast
    
    QueryOptions     options = QueryOptions.ComputeDetailedInfo | QueryOptions.HitDynamics | QueryOptions.HitKinematics | QueryOptions.HitStatics;
    Physics3D.Hit3D? hit     = frame.Physics3D.Linecast(position, targetPosition, ObjectLayerMask.Blocking, options);

    // 3. Update destination based on hits / exit if the distance is too short
    
    if (hit.HasValue == true)
    {
        direction = hit.Value.Point - position;
        FP magnitude = direction.MagnitudePrecise();
        if (magnitude < Distance)
        {
            if (magnitude < MinimumTravelDistance)
                return false;

            targetPosition = position + direction * FP._9 * FP._0_10;
        }
    }

    // 4. Set Movement, otherwise direct update of Transform3D
    
    Movement* movement = frame.TryGetComponent<Movement>(ownerRef);
    if (movement != null)
    {
        movement->Teleport(targetPosition);
    }
    else
    {
        transform3D->Position = targetPosition;
    }

    // 5. Spawn an effect if linked
    
    if (Effect.Id != 0)
    {
        Effects* effects = frame.TryGetComponent<Effects>(ownerRef);
        if (effects != null)
        {
            effects->AddEffect(frame, ownerRef, ownerRef, Effect, out _);
        }
    }

    // 6. Teleport was successful
    
    return true;
}

새로운 어빌리티 생성하기

다음은 FPS 템플릿에서 새로운 어빌리티 를 생성하기 위한 단계별 절차입니다.

  1. Quantum 솔루션에서 AbilityController에서 상속한 MyAbilityController를 새롭게 생성합니다.
  2. 컨트롤러에 직렬화할 수 있는 필드를 추가합니다 (환경 구성).
  3. 필요시, MyAbility 컴포넌트 정의와 롤백 가능한 데이터와 같은 데이터 구조체를 포함한 MyAbility.qtn을 생성합니다.
  4. 필요시 기본 속성을 오버라이드하고 컨트롤러에서 Initialize(), Deinitialize(), Activate(), Deactivate(), Update(), IsFinished() 메소드를 구현합니다.
  5. 사용할 수 있는 컨트롤러 인터페이스를 구현합니다 (예, IAttributesProvider, ...).
  6. quantum.code솔루션을 재 컴파일합니다.
  7. 유니티에서, 빈 게임 오브젝트를 생성하고 자식 객체로 비주얼 컴폰넌트 / 모델을 추가합니다.
  8. 게임 오브젝트에 Entity, EntityPrototype, EntityComponentController 그리고 EntityComponentAbility 스크립트를 추가합니다.
  9. Entity 컴포넌트 설정:
    • Transform SynchronizationSimple 또는 Error Correction
    • 엔티티를 소유하지 않고 어빌리티는 존재할 수 없으므로 Require Ownertrue로 설정
  10. EntityComponentController 컴포넌트에서, AbilityController 드롭다운 메뉴에서 MyAbilityController를 선택하고 정의된 속성으로 채워줍니다.
  11. EntityComponentAbility 컴포넌트에서 정의된 속성을 채워줍니다.
  12. 엔티티의 행동을 정의하기 위해 다른 엔티티 컴포넌트를 추가합니다. (EntityComponentMyAbility, ...)
  13. 엔티티의 프리팹을 생성합니다 (선택 사항)
  14. Quantum > Generate Asset Resources 메뉴를 통해 에셋 리소스 생성을 실행합니다.
  15. 이제 어빌리티를 사용할 준비가 되었습니다 - 레퍼런스 엔티티 프로토타입.
Back to top