Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Custom Package import - There is no active LocalizationSettings

Discussion in 'Package Manager' started by Bimaokai, Oct 4, 2021.

  1. Bimaokai

    Bimaokai

    Joined:
    Jul 21, 2017
    Posts:
    19
    Heyho

    I have been packaging my code into a custom package. In my Code i use Localization Tables.
    In the Runtime Assembly Folder i have a subfolder named "i18n" and in there is my Localization Settings.asset and in the subfolders the Locales and Tables assets.

    When i import this custom package into a new Unity 3D Project, it imports the necessary Localization Package and my complete package.

    As soon as i open then the scene in the package the following message appears
    "There is no active LocalizationSettings"

    I have such a settings file, but unity does not find it after import. Is there a way to tell unity to take mine when there is no other one?

    Thanks for help
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    You need to set the active LocalizationSettings, You can click on the settings file and it will give you an option in the inspector or you can do it via script LocalizationEditorSettings.ActiveLocalizationSettings.
     
  3. Bimaokai

    Bimaokai

    Joined:
    Jul 21, 2017
    Posts:
    19
    unfortunately i cannot find such a setting here....

    Created now an editor Class with a static Initializer and it works like a charm. Now my Localization Settings file from the package will be taken. When i have already a localization, it does not touch it, but also include my tables from the package. Very neat :)

    Tell me please if it's a problematic way to go like this.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEditor.Localization;
    5. using UnityEngine;
    6.  
    7. [InitializeOnLoad]
    8. public class LocalizationInitialization
    9. {
    10.     static LocalizationInitialization()
    11.     {
    12.         if (LocalizationEditorSettings.ActiveLocalizationSettings == null)
    13.         {
    14.             string[] foldersToSearch = { "Packages/zone.nonon.nononzonecontroller/Runtime/i18n/" };
    15.             string[] guids = AssetDatabase.FindAssets("Localization Settings", foldersToSearch);
    16.             string assetPath = AssetDatabase.GUIDToAssetPath(guids[0]);
    17.             UnityEngine.Localization.Settings.LocalizationSettings settings = AssetDatabase.LoadAssetAtPath<UnityEngine.Localization.Settings.LocalizationSettings>(assetPath);
    18.             LocalizationEditorSettings.ActiveLocalizationSettings = settings;
    19.  
    20.         }
    21.  
    22.     }
    23. }
    24.  
    It has now an error with the locales that are double, but i can delete em in the package if they already exist.
     
  4. Bimaokai

    Bimaokai

    Joined:
    Jul 21, 2017
    Posts:
    19
    Hey Karl. I extended now my script to set a new ActiveLocalization Setting and removing already existing locales when the package gets importet.

    Now i still have a problem i cannot solve: At the new project where i imported the package, the info is displayed correctly in Unity Editor Play Mode. As soon as i Build the Standalone Player, the information is not displayed anymore. In the logs i have the following error:

    Code (CSharp):
    1. System.Exception: Invalid path in TextDataProvider : 'C:/UnityProjects/Testimportli/Build/Testimportli_Data/StreamingAssets/aa/settings.json'.
    2. RuntimeData is null.  Please ensure you have built the correct Player Content.
    3. Addressables - Unable to load runtime data at location UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[[UnityEngine.AddressableAssets.Initialization.ResourceManagerRuntimeData, Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].
    4. OperationException : Addressables - Unable to load runtime data at location UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[[UnityEngine.AddressableAssets.Initialization.ResourceManagerRuntimeData, Unity.Addressables, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].
    5. UnityEngine.AddressableAssets.InvalidKeyException: Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown., Key=Locale, Type=UnityEngine.Localization.Locale
    6. OperationException : ChainOperation failed because dependent operation failed
    7. UnityEngine.AddressableAssets.InvalidKeyException: Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown., Key=Locale, Type=UnityEngine.Localization.Locale
    8. No Locale could be selected:
    9. No Locales were available. Did you build the Addressables?
    10. The following (3) IStartupLocaleSelectors were used:
    11.     UnityEngine.Localization.Settings.SpecificLocaleSelector
    12.     UnityEngine.Localization.Settings.SystemLocaleSelector
    13.     UnityEngine.Localization.Settings.CommandLineLocaleSelector
    14. OperationException : SelectedLocale is null
    15. OperationException : SelectedLocale is null
    16. OperationException : SelectedLocale is null
    17. OperationException : SelectedLocale is null
    18. OperationException : SelectedLocale is null
     
  5. Bimaokai

    Bimaokai

    Joined:
    Jul 21, 2017
    Posts:
    19
    Some more info. I found out, that when i do the "Build-->NewBuild-->Default Build Script" in the Adressable Groups Window it seems to work.

    Tried to do this in my Editor Script in the static Constructor
    Code (CSharp):
    1. AddressableAssetSettings.BuildPlayerContent();
    But if i import this with my package the following error is thrown:
    Code (CSharp):
    1. Calling NewScene from assembly reloading callbacks are not supported.
     
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    What version of Unity are you using? Did you build the Addressable assets?
     
  7. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    I think BuildPlayerContent calls NewScene. Try using a callback to trigger the build so it happens after the reload. Maybe https://docs.unity3d.com/ScriptReference/EditorApplication-delayCall.html
     
  8. Bimaokai

    Bimaokai

    Joined:
    Jul 21, 2017
    Posts:
    19
    Now it seems to work. I used
    Code (CSharp):
    1. EditorApplication.delayCall += BuildPlayerContent;  
    is that correct?

    Here the whole Localization Initializer Packet Script for Sharing:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEditor;
    3. using UnityEditor.AddressableAssets;
    4. using UnityEditor.AddressableAssets.Settings;
    5. using UnityEditor.AddressableAssets.Settings.GroupSchemas;
    6. using UnityEditor.Localization;
    7. using UnityEngine.Localization;
    8. using UnityEngine.Localization.Settings;
    9.  
    10. namespace zone.nonon
    11. {
    12.  
    13.     [InitializeOnLoad]
    14.     public class LocalizationInitialization
    15.     {
    16.         public static string ASSET_GROUP_LOCALES = "Localization-";
    17.  
    18.         static LocalizationInitialization()
    19.         {
    20.             if (LocalizationEditorSettings.ActiveLocalizationSettings == null)
    21.             {
    22.                 SetPackageActiveLocaleSettings();
    23.  
    24.             }
    25.             else
    26.             {
    27.                 DeleteDuplicateLocales();
    28.             }
    29.  
    30.             SetAssetGroupBundleNamingMode();
    31.         }
    32.  
    33.         /***
    34.         * This Method is
    35.         */
    36.         static void SetAssetGroupBundleNamingMode()
    37.         {
    38.             AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
    39.             List<AddressableAssetGroup> groups = settings.groups;
    40.             foreach (AddressableAssetGroup grp in groups)
    41.             {
    42.                 if (grp.Name.Contains(ASSET_GROUP_LOCALES))
    43.                 {
    44.                     BundledAssetGroupSchema schema = grp.GetSchema<BundledAssetGroupSchema>();
    45.                     if (!schema.BundleNaming.Equals(BundledAssetGroupSchema.BundleNamingStyle.AppendHash))
    46.                     {
    47.                         schema.BundleNaming = BundledAssetGroupSchema.BundleNamingStyle.AppendHash;
    48.                         grp.SetDirty(AddressableAssetSettings.ModificationEvent.EntryModified, schema.BundleNaming, false, true);    
    49.                         EditorApplication.delayCall += BuildPlayerContent;                          
    50.                     }
    51.                 }
    52.             }
    53.  
    54.         }
    55.  
    56.         static void BuildPlayerContent()
    57.         {
    58.             AddressableAssetSettings.BuildPlayerContent();          
    59.         }
    60.  
    61.  
    62.         static void SetPackageActiveLocaleSettings()
    63.         {
    64.             string[] foldersToSearch = { "Packages/zone.nonon.nononzonecontroller/Runtime/i18n/" };
    65.             string[] guids = AssetDatabase.FindAssets("Localization Settings", foldersToSearch);
    66.             string assetPath = AssetDatabase.GUIDToAssetPath(guids[0]);
    67.             LocalizationSettings settings = AssetDatabase.LoadAssetAtPath<LocalizationSettings>(assetPath);
    68.  
    69.             LocalizationEditorSettings.ActiveLocalizationSettings = settings;
    70.             ILocalesProvider locales = settings.GetAvailableLocales();
    71.         }
    72.  
    73.         static void DeleteDuplicateLocales()
    74.         {
    75.             IReadOnlyCollection<Locale> existingLocales = LocalizationEditorSettings.GetLocales();
    76.  
    77.             List<Locale> locales2Delete = new List<Locale>();
    78.             Dictionary<string, Locale> cache = new Dictionary<string, Locale>();
    79.  
    80.             foreach (Locale loc in existingLocales)
    81.             {
    82.                 Locale value;
    83.                 if (cache.TryGetValue(loc.LocaleName, out value))
    84.                 {
    85.                     locales2Delete.Add(loc);
    86.                 }
    87.                 else
    88.                 {
    89.                     cache.Add(loc.LocaleName, loc);
    90.                 }
    91.             }
    92.  
    93.             foreach (Locale loc in locales2Delete)
    94.             {
    95.                 LocalizationEditorSettings.RemoveLocale(loc);
    96.             }
    97.         }
    98.     }
    99. }
     
    karl_jones likes this.