특성
개요
AttributesSystem
은 외부 조건(예: 활성 상태일 때 +50% 속도 또는 특정 지역에 서 있을 때 +100% 대미지를 제공하는 효과)을 기반으로 값을 저장하고 계산할 수 있는 방법을 제공합니다.
설정
특성을 구현하기 위해서는, 2개의 작업이 수행되어야 합니다:
- 특성(일반적으로 행위자)을 사용하는 목표 엔티티의 컨트롤러는
IAttributesController
를 구현해야 합니다. 이렇게 하면 엔티티에 있는 특성을 제어하고 필요할 때 기본 상태로 재설정한 다음 수집된 값을 처리할 수 있습니다. - 특성(예: 효과 또는 영역)을 보유하고 있는 원천 엔티티의 컨트롤러가
IAttributesProvider
를 구현해야 합니다. 목표 엔티티에서 수집한 특성 값을 변경하는 데 사용됩니다.
속성 값은 원천 엔티티에 의해 계산되고 목표 엔티티에 수집할 수 있게 됩니다. 목표 엔티티와 원천 엔티티 간의 관계 및 속성 값의 계산을 다음 다이어그램으로 나타낼 수 있습니다.
AttributesSystem
은 Attributes
컴포넌트를 사용하여 각 엔티티에 대해 다음을 실행합니다.
- 목표 엔티티의 엔티티 컨트롤러에서
IAttributesController.Reset()
이 호출됩니다. 이 엔티티는Attributes
컴포넌트가 있는 엔티티입니다. 이때 모든 속성 컴포넌트를 기본값으로 재설정해야 합니다(일반적으로 곱셈의 경우 1.0, 더하기 수정자의 경우 0.0)(그림에서 빨간색 선으로 표시). - 등록된 모든 특성 공급자(예: 원천 엔티티)에서
IAttributeProvider.Collect()
가 호출됩니다. 각 제공자는 엔티티에 대한 내부 특성 값을 업데이트합니다(그림에서 녹색 선으로 표시). - 목표 엔티티의 엔티티 컨트롤러에서
IAttributesController.Process()
가 호출됩니다. 이 단계에서 모든 제공자의 값은 이미 곱/누적되었으며 최종 값은 추가 계산을 위해 준비되거나 컴포넌트 요구에 전달될 준비가 되었습니다 (그림에서 파란색선으로 표시).
주의: 엔티티의 특성 컬렉션에 참여하려면 Attributes.RegisterProvider()
또는 IAttributesProvider.RegisterOnCreate
를 통해 속성을 소유자 엔티티의 컬렉션에 등록해야 합니다. 특성을 등록 취소하려면 Attributes.UnregisterProvider()
를 호출해야 합니다.
예제
이 섹션에서는 AttributesSystem
이 FPS 템플릿에 포함된 DamageAttributeEffectController
구현과 어떻게 상호 작용하는지를 예시로 보여주고 있습니다.
C#
public unsafe sealed class DamageAttributeEffectController : AttributeEffectController, IAttributesProvider
{
//========== PUBLIC MEMBERS ===================================================================================
public FP PercentDamageDoneModifier = FP._0;
public FP PercentDamageReceivedModifier = FP._0;
//========== AttributeEffectController INTERFACE ==============================================================
protected override bool OnActivate(Frame frame, EntityRef entity, EntityRef target)
{
// 1. The effect is activated (returns true) only if the target has Damage attribute
DamageAttribute* damageAttribute = frame.TryGetComponent<DamageAttribute>(target);
return damageAttribute != null;
}
//========== IAttributesProvider INTERFACE ====================================================================
// 2. This attribute provider is registered to the pipeline when created
bool IAttributesProvider.RegisterOnCreate => true;
void IAttributesProvider.Collect(Frame frame, EntityRef entity, EntityRef target)
{
// 3. Collection phase, called each frame the effect exists
DamageAttribute* damageAttribute = frame.TryGetComponent<DamageAttribute>(target);
damageAttribute->DamageDoneMultiplier += PercentDamageDoneModifier * FP._0_01;
damageAttribute->DamageReceiveMultiplier += PercentDamageReceivedModifier * FP._0_01;
}
}
Back to top