Skip to content

GameModes Module

Technical Docs · Runtime Module

GameModes

Flow 기반 게임 모드 엔진

각 게임 세션의 실행 로직과 자원 생명주기를 캡슐화하는 모듈입니다. ScriptableObject 기반으로 에디터에서 직접 생성·조합하며, UniTask를 통한 비동기 큐 실행으로 모드 전환 시 순서 보장을 제공합니다.

ScriptableObject UniTask async FlowAsset Addressables

주요 구성 요소

🎮
GameMode
FlowAsset · ScriptableObject
게임 세션의 실행 로직을 담는 핵심 클래스. 에디터 메뉴 Forks / Game Mode로 생성하며, 비동기 큐를 통해 Begin/End 순서를 보장합니다.
ResourceHostresourceHostserialized
Task_queueTaskprivate
📦
ResourceHost
ScriptableObject
게임 모드 실행에 필요한 자원의 로드·언로드를 관리합니다. Lazy loading 방식으로 최초 Begin 시에만 로드하며, 서브클래스에서 가상 메서드를 오버라이드합니다.
bool_loadedlazy flag
🗺️
SceneResourceHost
ResourceHost (abstract)
Addressables로 씬을 Additive 로드하고 프리팹을 인스턴스화합니다. AsyncOperationHandle 관리 및 CancellationToken 연동을 처리합니다.
AssetReferencesceneBeginserialized
AssetReferenceGameObjectprefabserialized
IGameMode
interface : IDisposable
게임 모드의 공개 계약을 정의합니다. 외부에서는 이 인터페이스를 통해 모드를 제어하며, 구체 구현에 의존하지 않습니다.
UniTask BeginAsync(CancellationToken, Object owner)
UniTask EndAsync(CancellationToken)
void Dispose()

실행 생명주기

BeginAsync
1
EnqueueAsync
lock으로 보호된 큐에 작업 추가. 이전 Task 완료 후 순차 실행 보장
2
ResourceHost.BeginAsync
_loaded == false이면 OnLoadAsync 호출 후 플래그 설정. 이후 OnBeginAsync 호출
3
BeginSessionAsync
FlowAsset 세션 시작. owner 오브젝트의 Destroy에 연동된 CancellationToken 생성
EndAsync
1
EnqueueAsync
Begin이 완료되기를 기다린 후 실행. 동시 호출 시 자동으로 직렬화됨
2
EndSession
FlowAsset 세션 종료. CancellationTokenSource 취소 및 해제
3
ResourceHost.EndAsync
OnEndAsync 호출 후 OnUnloadAsync로 Addressable 씬·프리팹 해제

ResourceHost 확장 포인트

OnLoadAsync
최초 Begin 시 1회만 호출. 에셋 로드, 씬 초기화 등 무거운 작업 수행
호출 시점: _loaded == false인 첫 번째 BeginAsync
OnBeginAsync
매 Begin마다 호출. 로드된 자원의 활성화, 초기 상태 설정
호출 시점: OnLoadAsync 완료 후
OnEndAsync
매 End마다 호출. 자원 비활성화, 상태 정리
호출 시점: EndSession 완료 후, Unload 이전
OnUnloadAsync
End 시 항상 호출. Addressable 씬·프리팹 해제, 메모리 정리
호출 시점: OnEndAsync 완료 후

IGameMode

C# IGameMode.cs
public interface IGameMode : IDisposable
{
    UniTask BeginAsync(CancellationToken cancellationToken, Object owner);
    UniTask EndAsync(CancellationToken cancellationToken);
}
C# GameMode.cs — 핵심 로직
// 외부 공개 API — 큐에 등록 후 비동기 실행
public UniTask BeginAsync(CancellationToken ct, Object owner)
    => EnqueueAsync(() => BeginCoreAsync(ct, owner));

public UniTask EndAsync(CancellationToken ct)
    => EnqueueAsync(() => EndCoreAsync(ct));

// 큐 직렬화 — lock으로 보호, 이전 Task 완료 후 실행
private UniTask EnqueueAsync(Func<UniTask> operation)
{
    lock (_queueLock)
    {
        _queueTask = RunQueuedAsync(_queueTask, operation);
        return _queueTask.AsUniTask();
    }
}
💡
큐 직렬화 보장
BeginAsyncEndAsync를 동시에 호출해도 lock으로 보호된 Task 큐를 통해 항상 순차 실행됩니다. 이전 작업이 완료되기 전에 다음 작업이 시작되지 않습니다.
⚠️
resourceHost null 체크
BeginAsync 진입 시 Debug.Assert(resourceHost)가 실행됩니다. ResourceHost가 할당되지 않으면 에디터 콘솔에 Assert 에러가 발생합니다.
🔗
owner 생명주기 연동
FlowAsset 세션은 ownerGetCancellationTokenOnDestroy()와 연동됩니다. owner가 Destroy되면 세션이 자동으로 취소됩니다. MonoBehaviour, Component, GameObject만 지원됩니다.