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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

Bug Exceptions depending on initialization order?

Discussion in 'Localization Tools' started by arcnor, Mar 6, 2020.

  1. arcnor

    arcnor

    Joined:
    Nov 29, 2014
    Posts:
    21
    Hello,

    I'm having some trouble while using this package. I think that depending on initialization order I'm getting some exceptions:

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. UnityEngine.Localization.Settings.LocalizedDatabase`2[TTable,TEntry].GetTableLoadTable (UnityEngine.Localization.Tables.TableReference tableReference, UnityEngine.Localization.Locale locale) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:191)
    3. UnityEngine.Localization.Settings.LocalizedDatabase`2[TTable,TEntry].GetTableLoadTable (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] sharedTableDataOperation, UnityEngine.Localization.Locale locale) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:212)
    4. UnityEngine.Localization.Settings.LocalizedDatabase`2+<>c__DisplayClass23_0[TTable,TEntry].<GetTableLoadTable>b__0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] op) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:188)
    5. UnityEngine.ResourceManagement.ChainOperation`2[TObject,TObjectDependency].Execute () (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/AsyncOperations/ChainOperation.cs:34)
    6. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1[TObject].InvokeExecute () (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs:409)
    7. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1[TObject].<.ctor>b__33_0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle o) (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs:110)
    8. DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/Util/DelegateList.cs:69)
    9. UnityEngine.Debug:LogException(Exception)
    10. DelegateList`1:Invoke(AsyncOperationHandle) (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/Util/DelegateList.cs:73)
    11. UnityEngine.ResourceManagement.Util.DelayedActionManager:LateUpdate() (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/Util/DelayedActionManager.cs:169)
    12.  
    The offending like is:

    Code (CSharp):
    1. if (TableOperations.TryGetValue((locale.Identifier, tableReference), out var asyncOp))
    at LocalizedDatabase.cs, and the `null` reference is that `locale` object.

    This happens in my current scene when I just add some UI button (using TMP_Text) but it doesn't use localized strings itself, or (and this is the most strange one) even when I'm just editing a prefab and run the game, without changing anything else.

    May I know if I'm doing anything wrong, or if I need to change initialization order of some script for this to work properly? I've tried rebuilding addressables and things like that, but this obviously doesn't make much sense, as it works fine until I do on of those two things.

    Thanks in advance.
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Hi,
    I'll try and take a deeper look into this. Would you be able to file a bug report?
     
  3. arcnor

    arcnor

    Joined:
    Nov 29, 2014
    Posts:
    21
    Sure (you mean inside Unity itself, or does this package have a separate bugtracker?), although I cannot provide any more info than that, at least for now :) (or unless you tell me what to look for)

    Thanks!
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Just a normal bug report through Unity. It will help make sure the bug gets tracked and not forgotten about ;)
     
  5. arcnor

    arcnor

    Joined:
    Nov 29, 2014
    Posts:
    21
    Done, case 1225937. Thanks again, and I hope you get to the bottom of it.I had to disable the localization, as I cannot continue with the crash, so let me know if you need any debugging/testing or similar.
     
    karl_jones likes this.
  6. moomaru

    moomaru

    Joined:
    Jun 26, 2015
    Posts:
    4
    This Bug still exists when I try to use Localize Texture Component in latest release 0.6.1.
    here is log :
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. UnityEngine.Localization.Settings.LocalizedDatabase`2[TTable,TEntry].GetTableLoadTable (UnityEngine.Localization.Tables.TableReference tableReference, UnityEngine.Localization.Locale locale) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:191)
    3. UnityEngine.Localization.Settings.LocalizedDatabase`2[TTable,TEntry].GetTableLoadTable (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] sharedTableDataOperation, UnityEngine.Localization.Locale locale) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:212)
    4. UnityEngine.Localization.Settings.LocalizedDatabase`2+<>c__DisplayClass23_0[TTable,TEntry].<GetTableLoadTable>b__0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] op) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:188)
    5. UnityEngine.ResourceManagement.ChainOperation`2[TObject,TObjectDependency].Execute () (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/AsyncOperations/ChainOperation.cs:34)
    6. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1[TObject].InvokeExecute () (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs:409)
    7. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1[TObject].<.ctor>b__33_0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle o) (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs:110)
    8. DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/Util/DelegateList.cs:69)
    9. UnityEngine.Debug:LogException(Exception)
    10. DelegateList`1:Invoke(AsyncOperationHandle) (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/Util/DelegateList.cs:73)
    11. UnityEngine.ResourceManagement.Util.DelayedActionManager:LateUpdate() (at Library/PackageCache/com.unity.addressables@1.6.2/Runtime/ResourceManager/Util/DelayedActionManager.cs:169)
    12.  
    This happens only once at the beginning after running.
     
  7. arcnor

    arcnor

    Joined:
    Nov 29, 2014
    Posts:
    21
    @moomaru yeah, I forgot to mention my version, but I tested against 0.6.1 (and it still exists because I reported it 3 days ago :D).

    I've investigated a bit more, and I'm getting the error when using localized strings in `Awake()` and it seems that the list of locales is not populated at that point, although I'm using the asynchronous methods for them.
     
    karl_jones likes this.
  8. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Can you share the code?
     
  9. arcnor

    arcnor

    Joined:
    Nov 29, 2014
    Posts:
    21
    Right now the "code" was my game, so I sadly cannot do that.

    I also tried to set the `LocalizationSettings` script order before anything on my own game, but that did not fix the problem, so for now I've just removed this package.
     
  10. moomaru

    moomaru

    Joined:
    Jun 26, 2015
    Posts:
    4
    here is my code:

    Code (CSharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using UnityEngine.UI;
    7. using UnityEngine.Localization.Settings;
    8.  
    9. public enum localeType
    10. {
    11.     Chinese,
    12.     English,
    13.     Japanese
    14. };
    15.  
    16. [ExecuteInEditMode]
    17. public class LocalizationManager : MonoBehaviour
    18. {
    19.     private localeType lang = localeType.Japanese;
    20.  
    21.     public Button leftButton;
    22.     public Button rightButton;
    23.  
    24.     IEnumerator Start()
    25.     {
    26.         // Wait for the localization system to initialize, loading Locales, preloading etc.
    27.         yield return LocalizationSettings.InitializationOperation;
    28.  
    29.         // Set default locale
    30.         var locale = LocalizationSettings.AvailableLocales.Locales[(int)lang];
    31.         LocalizationSettings.SelectedLocale = locale;
    32.     }
    33.  
    34.     public void OnClickLefftButton()
    35.     {
    36.         Text text = leftButton.GetComponentInChildren<Text>();
    37.         SetTextLocale(text);
    38.     }
    39.  
    40.     public void OnClickRightButton()
    41.     {
    42.         Text text = rightButton.GetComponentInChildren<Text>();
    43.         SetTextLocale(text);
    44.     }
    45.  
    46.     public void SetTextLocale(Text text)
    47.     {
    48.         var nextLocaleIndex = (int)Enum.Parse(typeof(localeType), text.text);
    49.         var nextLocale = LocalizationSettings.AvailableLocales.Locales[nextLocaleIndex];
    50.  
    51.         var currentLocale = LocalizationSettings.SelectedLocale;
    52.         var currentLocaleIndex = LocalizationSettings.AvailableLocales.Locales.IndexOf(currentLocale);
    53.  
    54.         text.text = Enum.ToObject(typeof(localeType), currentLocaleIndex).ToString();
    55.  
    56.         LocalizationSettings.SelectedLocale = nextLocale;
    57.     }
    58. }
    59.  
    capture.png image is when I just select play in editor.
     

    Attached Files:

    karl_jones likes this.
  11. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Are the issues happening only in edit mode?
    We don't currently support edit mode(we will in the future), its a limitation of Addressables so this would explain why its not working.
     
  12. arcnor

    arcnor

    Joined:
    Nov 29, 2014
    Posts:
    21
    Not sure about their problems, but mine happened when playing, and I'm assuming theirs as well.
     
  13. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Their example script is using [ExecuteInEditMode] which I suspect is their problem.
     
  14. arcnor

    arcnor

    Joined:
    Nov 29, 2014
    Posts:
    21
    Ah, you're completely right, I missed that, sorry.
     
    karl_jones likes this.
  15. moomaru

    moomaru

    Joined:
    Jun 26, 2015
    Posts:
    4
    There is same error even I remove [ExecuteInEditMode].
    In my case, I inserted this code in LocalizedDatabase.cs.
    Code (CSharp):
    1.  
    2.         AsyncOperationHandle<TTable> GetTableLoadTable(TableReference tableReference, Locale locale)
    3.         {
    4.             if (tableReference.ReferenceType == TableReference.Type.Guid)
    5.             {
    6.                 // We need to load the SharedTableData so we can resolve the name of the table
    7.                 var sharedTableDataOperation = GetSharedTableData(tableReference);
    8.                 if (sharedTableDataOperation.IsDone)
    9.                     return GetTableLoadTable(sharedTableDataOperation, locale);
    10.                 return ResourceManager.CreateChainOperation(sharedTableDataOperation, op => GetTableLoadTable(op, locale));
    11.             }
    12.  
    13.             // ------------from here I inserted code----------------
    14.             if (locale==null)
    15.                 locale = LocalizationSettings.SelectedLocale;
    16.             //--------------------------------------------------------------
    17.            
    18.             if (TableOperations.TryGetValue((locale.Identifier, tableReference), out var asyncOp))
    19.                 return asyncOp;
    20.  
    21.             var tableAddress = AddressHelper.GetTableAddress(tableReference, locale.Identifier);
    22.             asyncOp = Addressables.LoadAssetAsync<TTable>(tableAddress);
    23.             RegisterTableOperation(asyncOp, locale.Identifier, tableReference.TableName);
    24.             return asyncOp;
    25.         }
     
  16. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Thats strange. If you dont provide a Locale then it should already be using LocalizationSettings.SelectedLocale earlier in the code. Ill try and reproduce the issue locally.
     
  17. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    I noticed a potential issue in your script

    Code (csharp):
    1. var locale = LocalizationSettings.AvailableLocales.Locales[(int)lang];
    We can not assume the order of the locales as they will be in the order that Addressables provides them, so (int)lang may not always be the same.

    Do something like this:

    Code (csharp):
    1. LocalizationSettings.AvailableLocales.GetLocale(SystemLanguage.Japanese);
    Ill make a note to sort them so that in the future you can do this.
     
  18. moomaru

    moomaru

    Joined:
    Jun 26, 2015
    Posts:
    4
    >We can not assume the order of the locales as they will be in the order that Addressables provides them, so (int)lang may not always be the same.

    Yep, I noticed it when build as a standalone app. now I changed to other way. thanks!

    Code (CSharp):
    1.  
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.Linq;
    6. using UnityEngine;
    7. using UnityEngine.UI;
    8. using UnityEngine.Localization.Settings;
    9.  
    10. public class LocalizationManager : MonoBehaviour
    11. {
    12.     private Dictionary<string, string> localeText = new Dictionary<string, string>() { { "ja", "Japanese" }, { "en", "English" }, { "zh", "Chinese" } };
    13.  
    14.     public Button leftButton;
    15.     public Button rightButton;
    16.  
    17.     public void OnClickLefftButton()
    18.     {
    19.         Text text = leftButton.GetComponentInChildren<Text>();
    20.         SetTextLocale(text);
    21.     }
    22.  
    23.     public void OnClickRightButton()
    24.     {
    25.         Text text = rightButton.GetComponentInChildren<Text>();
    26.         SetTextLocale(text);
    27.     }
    28.  
    29.     public void SetTextLocale(Text text)
    30.     {
    31.         var nextLocaleText = localeText.FirstOrDefault(dict => dict.Value == text.text);
    32.         var nextLocale = LocalizationSettings.AvailableLocales.Locales.Find(item => item.name.Contains(nextLocaleText.Key));
    33.  
    34.         var currentLocaleText = localeText.FirstOrDefault(dict => LocalizationSettings.SelectedLocale.name.Contains(dict.Key));
    35.         text.text = currentLocaleText.Value;
    36.  
    37.         LocalizationSettings.SelectedLocale = nextLocale;
    38.     }
    39. }
     
    Last edited: Mar 10, 2020
    karl_jones likes this.
  19. VDraks

    VDraks

    Joined:
    Jun 14, 2015
    Posts:
    1
    As I understand it the problem is as follows:

    In the method OnEnable() of LocalizeStringBehaviour LocalizedDatabase<StringTable, StringTableEntry>.GetTableEntryAsync() is executed (not directly):

    Code (CSharp):
    1. LocalizedDatabase<StringTable, StringTableEntry>.GetTableEntryAsync() at Settings\Database\LocalizedDatabase.cs:line 162
    2. LocalizedString.HandleLocaleChange() at \Localized Reference\LocalizedString.cs:line 146
    3. LocalizedString.ForceUpdate() at Localized Reference\LocalizedString.cs:line 137
    4. LocalizedString.RegisterChangeHandler() at Localized Reference\LocalizedString.cs:line 59
    5. LocalizeStringBehaviour.OnEnable() at Component Localizers\LocalizeStringBehaviour.cs:line 58
    Code (CSharp):
    1. public AsyncOperationHandle<TableEntryResult> GetTableEntryAsync(TableReference tableReference, TableEntryReference tableEntryReference)
    2.         {
    3.             // We need to initialize before we can use .LocalizationSettings.SelectedLocale.
    4.             var initOp = LocalizationSettings.InitializationOperation;
    5.             if (!initOp.IsDone)
    6.                 return ResourceManager.CreateChainOperation(initOp, (op) => GetTableEntryAsync(tableReference, tableEntryReference, LocalizationSettings.SelectedLocale));
    7.             return GetTableEntryAsync(tableReference, tableEntryReference, LocalizationSettings.SelectedLocale);
    8.         }
    Inside this method LocalizationSettings.SelectedLocale is used after checking for the initialization. Also there is a comment for that. So it is correct and there is no problem here.

    At the same time in the method OnEnable() of LocalizedAssetBehaviour LocalizedAssetDatabase.GetLocalizedAssetAsync is executed (not directly):

    Code (CSharp):
    1. LocalizedAssetDatabase.GetLocalizedAssetAsync<TMP_FontAsset>() at Settings\Database\LocalizedAssetDatabase.cs:line 55
    2. LocalizedAsset<TMP_FontAsset>.LoadAssetAsync() at Localized Reference\LocalizedAssetReference.cs:line 71
    3. LocalizedAsset<TMP_FontAsset>.HandleLocaleChange() at Localized Reference\LocalizedAssetReference.cs:line 87
    4. LocalizedAsset<TMP_FontAsset>.ForceUpdate() at Localized Reference\LocalizedAssetReference.cs:line 78
    5. LocalizedAsset<TMP_FontAsset>.RegisterChangeHandler() at Localized Reference\LocalizedAssetReference.cs:line 50
    6. LocalizedAssetBehaviour<TMP_FontAsset, LocalizedFont>.OnEnable() at Component Localizers\LocalizedAssetBehaviour.cs:line 30
    Code (CSharp):
    1. public AsyncOperationHandle<TObject> GetLocalizedAssetAsync<TObject>(TableReference tableReference, TableEntryReference tableEntryReference) where TObject : Object
    2.         {
    3.             return GetLocalizedAssetAsync<TObject>(tableReference, tableEntryReference, LocalizationSettings.SelectedLocale);
    4.         }
    Inside this method LocalizationSettings.SelectedLocale is used without any checking. So it is null here.

    If you look inside the method you can see call of GetTableEntryAsync with passed locale (wich is null).

    Code (CSharp):
    1. protected virtual AsyncOperationHandle<TObject> GetLocalizedAssetAsyncInternal<TObject>(TableReference tableReference, TableEntryReference tableEntryReference, Locale locale) where TObject : Object
    2.         {
    3.             var tableEntryOp = GetTableEntryAsync(tableReference, tableEntryReference, locale);
    4.             if (!tableEntryOp.IsDone)
    5.                 return ResourceManager.CreateChainOperation<TObject>(tableEntryOp, (op) => GetLocalizedAssetLoadAsset<TObject>(tableEntryOp, tableEntryReference));
    6.             return GetLocalizedAssetLoadAsset<TObject>(tableEntryOp, tableEntryReference);
    7.         }
    I assume that locale should not be passed here, and logic should be same as in LocalizeStringBehaviour. And first usage of LocalizationSettings.SelectedLocale should be inside GetTableEntryAsync.

    I hope it will be helpful
     
  20. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Ah yes, I see the problem. We are calling SelectedLocale on Assets before we have called LocalizationSettings.InitializationOperation. Thanks for the info, that has helped narrow down the issue. Ill get a fix out in the next release.
     
    shadoath likes this.
  21. ludenso

    ludenso

    Joined:
    Jun 24, 2019
    Posts:
    3
    Getting this bug when folow flag-example in the Quick Start Guide.

    There is no code i my script. Just three flags and a raw image with localize texture attached to it

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. UnityEngine.Localization.Settings.LocalizedDatabase`2[TTable,TEntry].GetTableLoadTable (UnityEngine.Localization.Tables.TableReference tableReference, UnityEngine.Localization.Locale locale) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:191)
    3. UnityEngine.Localization.Settings.LocalizedDatabase`2[TTable,TEntry].GetTableLoadTable (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] sharedTableDataOperation, UnityEngine.Localization.Locale locale) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:212)
    4. UnityEngine.Localization.Settings.LocalizedDatabase`2+<>c__DisplayClass23_0[TTable,TEntry].<GetTableLoadTable>b__0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] op) (at Library/PackageCache/com.unity.localization@0.6.1-preview/Runtime/Settings/Database/LocalizedDatabase.cs:188)
    5. UnityEngine.ResourceManagement.ChainOperation`2[TObject,TObjectDependency].Execute () (at Library/PackageCache/com.unity.addressables@1.5.1/Runtime/ResourceManager/AsyncOperations/ChainOperation.cs:34)
    6. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1[TObject].InvokeExecute () (at Library/PackageCache/com.unity.addressables@1.5.1/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs:401)
    7. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1[TObject].<.ctor>b__27_0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle o) (at Library/PackageCache/com.unity.addressables@1.5.1/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs:102)
    8. DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@1.5.1/Runtime/ResourceManager/Util/DelegateList.cs:69)
    9. UnityEngine.Debug:LogException(Exception)
    10. DelegateList`1:Invoke(AsyncOperationHandle) (at Library/PackageCache/com.unity.addressables@1.5.1/Runtime/ResourceManager/Util/DelegateList.cs:73)
    11. UnityEngine.ResourceManagement.Util.DelayedActionManager:LateUpdate() (at Library/PackageCache/com.unity.addressables@1.5.1/Runtime/ResourceManager/Util/DelayedActionManager.cs:169)
     
  22. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    7,846
    Hi,
    It's a know bug. It happens when the locales have not loaded yet. We will have a fix in the next release.
     
    shadoath likes this.
  23. ludenso

    ludenso

    Joined:
    Jun 24, 2019
    Posts:
    3
    Awesome. Just wanted to let you know that I experience the same - also how to easily replicate it.

    Thanks for a promising-looking package
     
    zkajo and karl_jones like this.