waygeek

How to Load TMP with tags use Addressables

Oct 19th, 2025
1,288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.04 KB | Source Code | 0 0
  1. using System.Collections.Generic;
  2. using Cysharp.Threading.Tasks;
  3. using UnityEngine;
  4. using UnityEngine.Localization;
  5. using UnityEngine.Localization.Settings;
  6. using UnityEngine.AddressableAssets;
  7. using UnityEngine.ResourceManagement.AsyncOperations;
  8. using WayHeart.Infrastructure.State;
  9. using WayHeart.Service.Audio;
  10. using Constant;
  11. using WayHeart.Service.Loader;
  12. using TMPro;
  13.  
  14. public class BootstrapState : IStateGame
  15. {
  16.     private readonly GameStateMachine _gameStateMachine;
  17.     private readonly AudioService _audioService;
  18.     readonly AssetLoader _assetLoader;
  19.  
  20.     public BootstrapState(GameStateMachine gameStateMachine, AudioService audioService, AssetLoader assetLoader)
  21.     {
  22.         _gameStateMachine = gameStateMachine;
  23.         _audioService = audioService;
  24.         _assetLoader = assetLoader;
  25.     }
  26.  
  27.     public async UniTask Enter()
  28.     {
  29.         await StartBackgroundResourceLoading();
  30.        
  31.         await _gameStateMachine.Enter<LoadMainMenuState>();
  32.     }
  33.  
  34.     public UniTask Exit()
  35.     {
  36.         return UniTask.CompletedTask;
  37.     }
  38.  
  39.     private async UniTask StartBackgroundResourceLoading()
  40.     {
  41.         _assetLoader.LoadAssetAsync<AudioClip>(ConstantAudioName.DefaultClick).Forget();
  42.         _assetLoader.LoadAssetAsync<AudioClip>(ConstantAudioName.DefaultDeny).Forget();
  43.  
  44.         _audioService.Ambient.PlayWhenReadyAsync(ConstantAudioName.MainMenuAmbient, true).Forget();
  45.  
  46.         // Завантажуємо шрифти та локалізацію паралельно
  47.         await UniTask.WhenAll(
  48.             LoadFontsAsync(),
  49.             LoadLocalization()
  50.         );
  51.     }
  52.  
  53.     private async UniTask LoadLocalization()
  54.     {
  55.         await LocalizationSettings.InitializationOperation;
  56.  
  57.         LoadSavedLanguage();
  58.  
  59.         await PreloadMainMenuTables();
  60.     }
  61.  
  62.     private void LoadSavedLanguage()
  63.     {
  64.         string savedLangCode = PlayerPrefs.GetString("SelectedLanguage", "");
  65.  
  66.         if (!string.IsNullOrEmpty(savedLangCode))
  67.         {
  68.             Locale savedLocale = LocalizationSettings.AvailableLocales.GetLocale(new LocaleIdentifier(savedLangCode));
  69.  
  70.             if (savedLocale != null)
  71.             {
  72.                 LocalizationSettings.SelectedLocale = savedLocale;
  73.                 return;
  74.             }
  75.         }
  76.  
  77.         Locale deviceLocale = LocalizationSettings.AvailableLocales.GetLocale(Application.systemLanguage);
  78.  
  79.         LocalizationSettings.SelectedLocale =
  80.             deviceLocale != null ? deviceLocale : LocalizationSettings.AvailableLocales.Locales[0];
  81.     }
  82.  
  83.     private async UniTask PreloadMainMenuTables()
  84.     {
  85.         var stringDatabase = LocalizationSettings.StringDatabase;
  86.  
  87.         var mainMenuTable = stringDatabase.GetTableAsync(ConstantLocalizationTabelName.MainMenu).ToUniTask();
  88.         var popupTable = stringDatabase.GetTableAsync(ConstantLocalizationTabelName.Popup).ToUniTask();
  89.  
  90.         await UniTask.WhenAll(mainMenuTable, popupTable);
  91.     }
  92.  
  93.     /// <summary>
  94.     /// Завантажує TextMesh Pro шрифти через Addressables.
  95.     /// Шрифти необхідні для TMP Fallback системи (емоджі та тег font) і мають бути в пам'яті до показу UI.
  96.     /// </summary>
  97.     private async UniTask LoadFontsAsync()
  98.     {
  99.         // Назви шрифтів з Addressables
  100.         string[] fontNames = new[]
  101.         {
  102.             "FramerSans300 SDF",
  103.             "FramerSans400 SDF",
  104.             "FramerSans600 SDF"
  105.         };
  106.  
  107.         // Завантажуємо всі шрифти паралельно та отримуємо результати через кортежі
  108.         var (font300, font400, font600) = await UniTask.WhenAll(
  109.             LoadSingleFontAsync(fontNames[0]),
  110.             LoadSingleFontAsync(fontNames[1]),
  111.             LoadSingleFontAsync(fontNames[2])
  112.         );
  113.  
  114.         // Перевіряємо що всі шрифти успішно завантажились
  115.         if (font300 != null && font400 != null && font600 != null)
  116.         {
  117.             // Оновлюємо TMP Settings щоб теги <font="FontName"> працювали з новими екземплярами шрифтів
  118.             TMP_Settings.fallbackFontAssets = new List<TMP_FontAsset> { font300, font400, font600 };
  119.             TMP_Settings.defaultFontAsset = font300;
  120.  
  121.             // Оновлюємо внутрішню таблицю TMP для пошуку шрифтів через теги <font>
  122.             MaterialReferenceManager.AddFontAsset(font300);
  123.             MaterialReferenceManager.AddFontAsset(font400);
  124.             MaterialReferenceManager.AddFontAsset(font600);
  125.         }
  126.         else
  127.         {
  128.             Debug.LogWarning("❌ Не всі шрифти завантажились. TMP Settings не оновлено.");
  129.         }
  130.     }
  131.  
  132.     /// <summary>
  133.     /// Завантажує окремий TMP шрифт через Addressables.
  134.     /// При помилці логує її, але не блокує загрузку (graceful degradation).
  135.     /// </summary>
  136.     private async UniTask<TMP_FontAsset> LoadSingleFontAsync(string fontName)
  137.     {
  138.         try
  139.         {
  140.             var handle = Addressables.LoadAssetAsync<TMP_FontAsset>(fontName);
  141.             await handle.ToUniTask();
  142.  
  143.             if (handle.Status == AsyncOperationStatus.Succeeded)
  144.             {
  145.                 Debug.Log($"✓ Завантажено шрифт: {fontName}");
  146.                 return handle.Result;
  147.             }
  148.             else
  149.             {
  150.                 Debug.LogWarning($"❌ Помилка завантаження шрифту {fontName}: {handle.OperationException}");
  151.                 return null;
  152.             }
  153.         }
  154.         catch (System.Exception ex)
  155.         {
  156.             // Не блокуємо запуск гри при помилці завантаження шрифтів
  157.             Debug.LogWarning($"❌ Помилка завантаження шрифту {fontName}: {ex.Message}");
  158.             return null;
  159.         }
  160.     }
  161. }
  162.  
Advertisement
Add Comment
Please, Sign In to add comment