This document is about: QUANTUM 2
SWITCH TO

엔티티 컨텍스트

EntityContext는 엔티티 컴포넌트에 대한 캐시 된 참조를 포함하는 특수 객체입니다. 따라서 단일 프레임에서 특정 컴포넌트에 여러 번 액세스하는 데 드는 성능 비용을 절감할 수 있습니다.

C#

foreach (EntityComponentPointerPair<AI> pair in frame.Unsafe.GetComponentBlockIterator<AI>())
{
    EntityRef entity = pair.Entity;
    if (frame.IsCulled(entity) == true)
        continue;
    if (frame.DestroyPending(entity) == true)
        continue;

    // Prepare EntityContext to currently iterated EntityRef
    frame.EntityContext.Set(frame, entity);
    
    pair.Component->Update(frame, entity);
    
    // Reset EntityContext, important to prevent garbage being stored
    frame.EntityContext.Reset();
}

내부적으로는 pair.Component->Update(frame, entity)는 엔티티 컴포넌트에 자주 액세스하는 많은 AI 작업 및 의사 결정을 실행할 수 있는 상태 머신을 실행합니다. EntityContext를 사용하면 컴포넌트 조회가 한 번만 수행되고 이후 조회에 대한 오버헤드는 단일 메소드 호출 + bool 체크의 조회 결과로 나타납니다.

다음 클래스들은 게임 플레이 HFSM 로직에 사용되고 frame.EntityContext.AIMemory에 대한 접근을 포함합니다. 이 중 최소 2개를 단일 프레임에서 실행하면 성능이 최적화됩니다.

C#

public unsafe sealed class DamagedByEntityHFSMDecision : HFSMDecision
{
    public AIParamFP MinAmount = (FP)15;

    public override bool Decide(Frame frame, EntityRef entity)
    {
        AIMemoryRecord* damageRecord = frame.EntityContext.AIMemory->GetRecord(frame, EMemoryType.Damage);

        return damageRecord != null && damageRecord->Data.Damage->Amount > MinAmount.Resolve(frame, frame.EntityContext.AIBlackboard, frame.EntityContext.AIConfig);
    }
}

C#

public unsafe sealed class HasMemoryRecordHFSMDecision : HFSMDecision
{
    public EMemoryType MemoryType;

    public override bool Decide(Frame frame, EntityRef entity)
    {
        return frame.EntityContext.AIMemory->GetRecord(frame, MemoryType) != null;
    }
}

C#

public unsafe sealed class ClearMemoryAIAction : AIAction
{
    public EMemoryType MemoryType;

    public override void Update(Frame frame, EntityRef entity)
    {
        frame.EntityContext.AIMemory->RemoveRecords(frame, MemoryType);
    }
}
Back to top