1. 목적 / 기능 요약

2. 관련 주요 스크립트 목록

스크립트 파일 설명
SceneIntro.cs 인트로 씬의 전반적인 처리 로직
AddressableSettingsLoader.cs 설정 ScriptableObject 로드
UIWindowLoadSaveData.cs 저장된 플레이 정보 목록을 표시하는 UI 윈도우

3. 스크립트 동작 흐름

SceneIntro.cs

private void Awake()
{
    InitializeAddressableSettingLoader();
}
/// <summary>
/// GGemCo Settings 파일 읽어오기
/// </summary>
private void InitializeAddressableSettingLoader()
{
    GameObject gameObjectAddressableSettingsLoader = new GameObject("AddressableSettingsLoader");
    addressableSettingsLoader = gameObjectAddressableSettingsLoader.AddComponent<AddressableSettingsLoader>();
    _ = addressableSettingsLoader.InitializeAsync();
    addressableSettingsLoader.OnLoadSettings += InitializeSlotMetaDataManager;
}
/// <summary>
/// 세이븓 데이터 슬롯 정보를 읽어서 버튼 처리 
/// </summary>
private void InitializeSlotMetaDataManager(GGemCoSettings settings, GGemCoPlayerSettings playerSettings,
    GGemCoMapSettings mapSettings, GGemCoSaveSettings saveSettings)
{
    slotMetaDatController = new SlotMetaDatController(saveSettings.SaveDataFolderName, saveSettings.saveDataMaxSlotCount);
    if (uIWindowLoadSaveData != null)
    {
        uIWindowLoadSaveData.InitializeSaveDataSlots(saveSettings, slotMetaDatController);
    }

    saveDataSettings = saveSettings;
}

AddressableSettingsLoader.cs

/// <summary>
/// Addressable Settings를 비동기적으로 로드하는 함수
/// </summary>
public async Task InitializeAsync()
{
    await LoadAllSettingsAsync();
}

/// <summary>
/// 모든 설정 파일을 Addressables에서 로드
/// </summary>
private async Task LoadAllSettingsAsync()
{
    try
    {
        // 여러 개의 설정을 병렬적으로 로드
        var settingsTask = LoadSettingsAsync<GGemCoSettings>(ConfigAddressables.KeySettings);
        var playerSettingsTask = LoadSettingsAsync<GGemCoPlayerSettings>(ConfigAddressables.KeyPlayerSettings);
        var mapSettingsTask = LoadSettingsAsync<GGemCoMapSettings>(ConfigAddressables.KeyMapSettings);
        var saveSettingsTask = LoadSettingsAsync<GGemCoSaveSettings>(ConfigAddressables.KeySaveSettings);

        // 모든 작업이 완료될 때까지 대기
        await Task.WhenAll(settingsTask, playerSettingsTask, mapSettingsTask, saveSettingsTask);

        // 결과 저장
        settings = settingsTask.Result;
        playerSettings = playerSettingsTask.Result;
        mapSettings = mapSettingsTask.Result;
        saveSettings = saveSettingsTask.Result;

        // 이벤트 호출
        OnLoadSettings?.Invoke(settings, playerSettings, mapSettings, saveSettings);
    }
    catch (Exception ex)
    {
        GcLogger.LogError($"설정 로딩 중 오류 발생: {ex.Message}");
    }
}

/// <summary>
/// 제네릭을 사용하여 Addressables에서 설정을 로드하는 함수
/// </summary>
private async Task<T> LoadSettingsAsync<T>(string key) where T : ScriptableObject
{
    // 키가 Addressables에 등록되어 있는지 확인
    var locationsHandle = Addressables.LoadResourceLocationsAsync(key);
    await locationsHandle.Task;

    ...

    // 설정 로드
    AsyncOperationHandle<T> handle = Addressables.LoadAssetAsync<T>(key);
    T asset = await handle.Task;

    // 핸들 해제
    Addressables.Release(locationsHandle);
    return asset;
}

UIWindowLoadSaveData.cs

/// <summary>
/// Settings 에서 최대 슬롯 개수를 가져와 UIElementSaveDataSlot 을 만든다.
/// </summary>
public void InitializeSaveDataSlots(GGemCoSaveSettings saveSettings, SlotMetaDatController pslotMetaDatController)
{
    if (elementSaveDataSlot == null || containerElementSaveDataSlot == null) return;
    int maxSlotCount = saveSettings.saveDataMaxSlotCount;
    slotMetaDatController = pslotMetaDatController;   
    List<SlotMetaInfo> slotMetaInfos = slotMetaDatController.GetMetaDataSlots();
    for (int i = 0; i < maxSlotCount; i++)
    {
		    ...
        SlotMetaInfo slotMetaInfo = slotMetaInfos[i];
        ...
    }
}

4. 특이사항 및 주의점

5. 주요 스크립트 설명