PART 3 - 강의 2/4
런타임 Data Layer 제어
C++에서 Data Layer 상태 변경 및 확인
01
UDataLayerManager
Data Layer 런타임 제어의 핵심 클래스
C++ - DataLayerManager 접근
#include "WorldPartition/DataLayer/DataLayerManager.h"
#include "WorldPartition/DataLayer/DataLayerAsset.h"
void AMyActor::ControlDataLayer()
{
UWorld* World = GetWorld();
if (!World) return;
// DataLayerManager 획득
UDataLayerManager* DataLayerManager =
UDataLayerManager::GetDataLayerManager(World);
if (!DataLayerManager)
{
UE_LOG(LogTemp, Warning, TEXT("DataLayerManager not available"));
return;
}
// 이제 DataLayerManager를 통해 레이어 제어 가능
}
02
Data Layer 상태 변경
SetDataLayerRuntimeState API
C++ - MyDataLayerController.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "WorldPartition/DataLayer/DataLayerAsset.h"
#include "MyDataLayerController.generated.h"
UCLASS()
class MYGAME_API AMyDataLayerController : public AActor
{
GENERATED_BODY()
public:
// Data Layer 상태 변경
UFUNCTION(BlueprintCallable, Category = "Data Layer")
void SetDataLayerState(UDataLayerAsset* DataLayer,
EDataLayerRuntimeState NewState);
// 다중 Data Layer 상태 변경
UFUNCTION(BlueprintCallable, Category = "Data Layer")
void SetMultipleDataLayerStates(
const TArray<UDataLayerAsset*>& DataLayers,
EDataLayerRuntimeState NewState);
// 현재 상태 조회
UFUNCTION(BlueprintCallable, Category = "Data Layer")
EDataLayerRuntimeState GetDataLayerState(UDataLayerAsset* DataLayer) const;
// 상태 변경 완료 대기
UFUNCTION(BlueprintCallable, Category = "Data Layer")
bool IsDataLayerStateChangeComplete(UDataLayerAsset* DataLayer) const;
};
C++ - MyDataLayerController.cpp
#include "MyDataLayerController.h"
#include "WorldPartition/DataLayer/DataLayerManager.h"
void AMyDataLayerController::SetDataLayerState(
UDataLayerAsset* DataLayer,
EDataLayerRuntimeState NewState)
{
if (!DataLayer)
{
UE_LOG(LogTemp, Warning, TEXT("Invalid DataLayer asset"));
return;
}
UWorld* World = GetWorld();
if (!World) return;
UDataLayerManager* DataLayerManager =
UDataLayerManager::GetDataLayerManager(World);
if (DataLayerManager)
{
DataLayerManager->SetDataLayerRuntimeState(
DataLayer,
NewState,
true // bIsRecursive - 자식 레이어도 포함
);
UE_LOG(LogTemp, Log, TEXT("DataLayer '%s' state changed to %d"),
*DataLayer->GetName(), (int32)NewState);
}
}
void AMyDataLayerController::SetMultipleDataLayerStates(
const TArray<UDataLayerAsset*>& DataLayers,
EDataLayerRuntimeState NewState)
{
for (UDataLayerAsset* DataLayer : DataLayers)
{
SetDataLayerState(DataLayer, NewState);
}
}
EDataLayerRuntimeState AMyDataLayerController::GetDataLayerState(
UDataLayerAsset* DataLayer) const
{
if (!DataLayer) return EDataLayerRuntimeState::Unloaded;
if (UWorld* World = GetWorld())
{
if (UDataLayerManager* Manager =
UDataLayerManager::GetDataLayerManager(World))
{
return Manager->GetDataLayerEffectiveRuntimeState(DataLayer);
}
}
return EDataLayerRuntimeState::Unloaded;
}
bool AMyDataLayerController::IsDataLayerStateChangeComplete(
UDataLayerAsset* DataLayer) const
{
if (!DataLayer) return true;
if (UWorld* World = GetWorld())
{
if (UDataLayerManager* Manager =
UDataLayerManager::GetDataLayerManager(World))
{
EDataLayerRuntimeState CurrentState =
Manager->GetDataLayerEffectiveRuntimeState(DataLayer);
EDataLayerRuntimeState TargetState =
Manager->GetDataLayerRuntimeState(DataLayer);
return CurrentState == TargetState;
}
}
return true;
}
03
Target vs Effective State
상태 전환 중 구분
Target State
GetDataLayerRuntimeState()가 반환. 설정된 목표 상태입니다.
Effective State
GetDataLayerEffectiveRuntimeState()가 반환. 실제 현재 상태입니다.
C++
// 상태 변경 완료 여부 확인
void AMyActor::CheckStateTransition(UDataLayerAsset* DataLayer)
{
if (UDataLayerManager* Manager =
UDataLayerManager::GetDataLayerManager(GetWorld()))
{
EDataLayerRuntimeState TargetState =
Manager->GetDataLayerRuntimeState(DataLayer);
EDataLayerRuntimeState EffectiveState =
Manager->GetDataLayerEffectiveRuntimeState(DataLayer);
if (TargetState != EffectiveState)
{
UE_LOG(LogTemp, Log,
TEXT("DataLayer '%s' transitioning: Target=%d, Current=%d"),
*DataLayer->GetName(),
(int32)TargetState,
(int32)EffectiveState);
}
else
{
UE_LOG(LogTemp, Log,
TEXT("DataLayer '%s' transition complete: %d"),
*DataLayer->GetName(),
(int32)EffectiveState);
}
}
}
비동기 전환
상태 변경은 비동기적으로 수행됩니다. SetDataLayerRuntimeState 호출 직후에는 Target과 Effective가 다를 수 있으며, 스트리밍이 완료되면 일치합니다.
04
상태 변경 완료 대기
비동기 전환 완료 확인
C++
// 상태 변경 후 콜백 실행
void AMyGameMode::ActivateDataLayerWithCallback(
UDataLayerAsset* DataLayer,
TFunction<void()> OnComplete)
{
if (!DataLayer) return;
// 상태 변경 요청
if (UDataLayerManager* Manager =
UDataLayerManager::GetDataLayerManager(GetWorld()))
{
Manager->SetDataLayerRuntimeState(
DataLayer, EDataLayerRuntimeState::Activated, true);
}
// 완료 대기
GetWorldTimerManager().SetTimer(
DataLayerCheckHandle,
[this, DataLayer, OnComplete]()
{
if (UDataLayerManager* Manager =
UDataLayerManager::GetDataLayerManager(GetWorld()))
{
EDataLayerRuntimeState Current =
Manager->GetDataLayerEffectiveRuntimeState(DataLayer);
EDataLayerRuntimeState Target =
Manager->GetDataLayerRuntimeState(DataLayer);
if (Current == Target)
{
GetWorldTimerManager().ClearTimer(DataLayerCheckHandle);
OnComplete();
}
}
},
0.1f,
true);
}
SUMMARY
핵심 요약
- UDataLayerManager::GetDataLayerManager()로 매니저 접근
- SetDataLayerRuntimeState()로 상태 변경 (Unloaded/Loaded/Activated)
- bIsRecursive=true로 자식 레이어도 함께 제어
- Target State는 목표, Effective State는 현재 실제 상태
- 상태 변경은 비동기 - 완료 여부를 폴링으로 확인
PRACTICE
도전 과제
배운 내용을 직접 실습해보세요
실습 1: C++에서 Data Layer 상태 변경
UWorldPartitionSubsystem의 SetDataLayerRuntimeState()를 사용하여 Runtime Data Layer의 상태를 Unloaded/Loaded/Activated로 변경하는 코드를 작성하세요. 상태 변경 완료를 콜백으로 감지합니다.
실습 2: 블루프린트 Data Layer 제어
블루프린트에서 Data Layer 상태를 변경하는 노드를 사용하여, 레버를 당기면 숨겨진 던전 영역이 나타나는 게임플레이를 구현하세요. IsDataLayerRuntimeStateReady로 로딩 완료를 확인합니다.
심화 과제
여러 Data Layer의 상태를 중앙에서 관리하고, 의존성(레이어 A 활성화 전에 레이어 B 비활성화)을 처리하는 DataLayerStateManager를 구현하세요. 세이브/로드 시 레이어 상태 직렬화를 포함합니다.