어빌리티
개요
AbilitiesSystem
은 특정 엔티티(일반적으로 액터)와 관련된 사용자 지정 작업을 실행합니다.
기능과 속성
FPS 템플릿에는 어빌리티 구현에 다음과 같은 기능들이 포함되어 있습니다.
- 모든 어빌리티는 실체입니다.
- 어빌리티는 켜기/끄기 또는 일회성으로 토글 할 수 있습니다.
- 어빌리티는 특정 양의 충전 및/또는 충전 타이머가 있습니다.
- 런타임에 동적으로 기능을 추가하거나 제거할 수 있습니다.
- 어빌리티의 순차적 실행은 각 어빌리티에 대해 정의된 전체적인 재사용 대기 시간에 의해 제약을 받습니다(0일 수 있음).
- 여러 어빌리티가 동시에 활성화될 수 있습니다.
기본 어빌리티 구현은 필요에 따라 확장할 수 있으며 기본적으로 다음 속성들이 제공됩니다:
Cooldown
: 어빌리티 재사용에 필요한 시간Global Cooldown
: 사용 후의 전역 어빌리티의 쿨 다운Recharge
: 어빌리티 충전하는 경우/할 때의 제어Recharge Time
: 1 충전을 얻기 위해 필요한 시간Max Charges
: 사용량은 어빌리티의 전체 충전 량에 포함됩니다.Start Charges
: 어빌리티가 추가될 때 엔티티에 제공된 초기 충전 양Activation Frame
: 어빌리티가 예측/예측 프레임에서 실행되는지 여부의 제어
실행 흐름
어빌리티는 즉각적인 행동이 아닙니다. 처음에는 AbilitiesDesires
로 작성되고 나중에 같은 프레임에서 Update에서 실행됩니다. 어빌리티의 수명은 IsFinished
속성에 의해 제어되며, 속성이 true
로 설정되면 어빌리티가 비활성화됩니다. 다음 그림은 AbilityController
의 API와 실행 흐름을 보여줍니다.
구현 예제
이 섹션에서는 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
)이 추가됩니다. 모든 속성은 유니티 인스펙터에서 조정할 수 있습니다.
TeleportAbility
는 활성화되면 다음과 같은 로직을 실행합니다.
- 이 기능은 물리학 라인 캐스트가 전방의 이동 거리를 확인하게 합니다.
Movement
컴포넌트를 가진 어빌리티 소유자인 경우 텔레포트는 이 컴포넌트를 통해 실행되며 그렇지 않으면,Transform3D
컴포넌트에 직적 쓰게 됩니다.- 선택적으로 소유자 엔티티에 효과가 추가됩니다(예: 몇 초 동안의 속도 향상).
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 템플릿에서 새로운 어빌리티 를 생성하기 위한 단계별 절차입니다.
- Quantum 솔루션에서
AbilityController
에서 상속한MyAbilityController
를 새롭게 생성합니다. - 컨트롤러에 직렬화할 수 있는 필드를 추가합니다 (환경 구성).
- 필요시,
MyAbility
컴포넌트 정의와 롤백 가능한 데이터와 같은 데이터 구조체를 포함한MyAbility.qtn
을 생성합니다. - 필요시 기본 속성을 오버라이드하고 컨트롤러에서
Initialize()
,Deinitialize()
,Activate()
,Deactivate()
,Update()
,IsFinished()
메소드를 구현합니다. - 사용할 수 있는 컨트롤러 인터페이스를 구현합니다 (예,
IAttributesProvider
, ...). quantum.code
솔루션을 재 컴파일합니다.- 유니티에서, 빈 게임 오브젝트를 생성하고 자식 객체로 비주얼 컴폰넌트 / 모델을 추가합니다.
- 게임 오브젝트에
Entity
,EntityPrototype
,EntityComponentController
그리고EntityComponentAbility
스크립트를 추가합니다. Entity
컴포넌트 설정:Transform Synchronization
을Simple
또는Error Correction
- 엔티티를 소유하지 않고 어빌리티는 존재할 수 없으므로
Require Owner
를true
로 설정
EntityComponentController
컴포넌트에서,AbilityController
드롭다운 메뉴에서MyAbilityController
를 선택하고 정의된 속성으로 채워줍니다.EntityComponentAbility
컴포넌트에서 정의된 속성을 채워줍니다.- 엔티티의 행동을 정의하기 위해 다른 엔티티 컴포넌트를 추가합니다. (
EntityComponentMyAbility
, ...) - 엔티티의 프리팹을 생성합니다 (선택 사항)
Quantum > Generate Asset Resources
메뉴를 통해 에셋 리소스 생성을 실행합니다.- 이제 어빌리티를 사용할 준비가 되었습니다 - 레퍼런스 엔티티 프로토타입.