Search Unity

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

  2. Unity 2022.1 is now available as the latest Tech release.
    Dismiss Notice
  3. Improve your project's performance with our new guide on profiling in Unity.
    Dismiss Notice

Nested LocalizedString does not refresh

Discussion in 'Localization Tools' started by hadesfury, Oct 6, 2021.

  1. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    51
    Hello,

    I don’t have that much time to report a bug with a correct use case but I encounter a small annoyment with the nested LocalizedString system.

    upload_2021-10-6_16-15-27.png

    This contains a LocalizeStringEvent that should be updated each time _populationCount or _populationLevel change.

    In my update function, I just do the following
    Code (CSharp):
    1.              
    2. _milestonePopulationCountLocalisedVariable.Value = nextMilestoneInfo._populationCount;
    3. _milestonePopulationLevelLocalisedVariable.Value = nextMilestoneInfo._populationLevel;
    4.  
    those two variables are assigned in my Start function from a reference assigned in the editor "MilestoneText" in the image
    Code (CSharp):
    1.  
    2. [SerializeField] private LocalizeStringEvent _milestoneText;
    3.  
    4. private LocalizedString _nextMilestoneLocalizedString;
    5. private IntVariable _milestonePopulationCountLocalisedVariable;
    6. private IntVariable _milestonePopulationLevelLocalisedVariable;
    7.  
    8. private void Start()
    9. {
    10.     _nextMilestoneLocalizedString = _milestoneText.StringReference["_nextMilestone"] as LocalizedString;
    11.     _milestonePopulationCountLocalisedVariable = _nextMilestoneLocalizedString["_populationCount"] as IntVariable;
    12.     _milestonePopulationLevelLocalisedVariable = _nextMilestoneLocalizedString["_populationLevel"] as IntVariable;
    13. }
    14.  
    The main problem is that changing the IntVariable(s) values does not update the Text value.

    First "workaround", I forced the LocalizeStringEvent to refresh
    _milestoneText.RefreshString();
    .

    But, it comes with a pretty awful drawback, each time I exited the "play mode" it crashes with two call stacks

    Code (CSharp):
    1. Exception: Reentering the Update method is not allowed.  This can happen when calling WaitForCompletion on an operation while inside of a callback.
    2. UnityEngine.ResourceManagement.ResourceManager.Update (System.Single unscaledDeltaTime) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/ResourceManager.cs:1067)
    3. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject].WaitForCompletion () (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/AsyncOperations/AsyncOperationHandle.cs:194)
    4. UnityEngine.Localization.LocalizedString.GetLocalizedString () (at Library/PackageCache/com.unity.localization@1.0.3/Runtime/Localized Reference/LocalizedString.cs:249)
    5. Pandora.Managers.GameManager.SendMessageEvent (Pandora.Events.GameEvent gameEvent) (at Assets/Pandora/Scripts/Managers/GameManager.cs:914)
    6. Pandora.Managers.EventManager.TriggerEvent[TYPE_EVENT] (TYPE_EVENT gameEvent) (at Assets/Pandora/Scripts/Managers/EventManager.cs:90)
    7. Pandora.Managers.SaveManager.SaveFileContent (Pandora.SaveData saveData, System.String saveName) (at Assets/Pandora/Scripts/Managers/SaveManager.cs:241)
    8. Pandora.Managers.LoadingManager.ApplicationOnLogMessageReceived (System.String condition, System.String stacktrace, UnityEngine.LogType type) (at Assets/Pandora/Scripts/Managers/LoadingManager.cs:59)
    9. UnityEngine.Application.CallLogCallback (System.String logString, System.String stackTrace, UnityEngine.LogType type, System.Boolean invokedOnMainThread) (at <ca496b8c93454b2f9b9924292c19379f>:0)
    10. UnityEngine.Debug:LogException(Exception)
    11. DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/Util/DelegateList.cs:73)
    12. UnityEngine.Localization.Components.LocalizeStringEvent:RefreshString()
    13. Pandora.Ui.IngameUiLayout:Update() (at Assets/Pandora/Scripts/Ui/IngameUiLayout.cs:368)
    14.  
    Code (CSharp):
    1. MissingReferenceException: The object of type 'LocalizationBehaviour' has been destroyed but you are still trying to access it.
    2. Your script should either check if it is null or you should not destroy the object.
    3. UnityEngine.MonoBehaviour.StartCoroutine (System.Collections.IEnumerator routine) (at <ca496b8c93454b2f9b9924292c19379f>:0)
    4. UnityEngine.Localization.LocalizationBehaviour.ReleaseNextFrame (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle handle) (at Library/PackageCache/com.unity.localization@1.0.3/Runtime/Utilities/LocalizationBehaviour.cs:29)
    5. UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationBase`1+<>c__DisplayClass57_0[TObject].<add_CompletedTypeless>b__0 (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject] s) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/AsyncOperations/AsyncOperationBase.cs:291)
    6. DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/Util/DelegateList.cs:69)
    7. UnityEngine.Debug:LogException(Exception)
    8. DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/Util/DelegateList.cs:73)
    9. UnityEngine.Localization.Components.LocalizeStringEvent:RefreshString()
    10. Pandora.Ui.IngameUiLayout:Update() (at Assets/Pandora/Scripts/Ui/IngameUiLayout.cs:368)
    11.  
    So second workaround to avoid that and sorry it is ugly but it prevents the crash as my values are not changing that often.
    Code (CSharp):
    1.  
    2. if ((_milestonePopulationCountLocalisedVariable.Value != nextMilestoneInfo._populationCount) || (_milestonePopulationLevelLocalisedVariable.Value != nextMilestoneInfo._populationLevel))
    3. {
    4.     _milestonePopulationCountLocalisedVariable.Value = nextMilestoneInfo._populationCount;
    5.     _milestonePopulationLevelLocalisedVariable.Value = nextMilestoneInfo._populationLevel;
    6.     _milestoneText.RefreshString();
    7. }
    8.  
    Sorry for the length of this post .. but am I right in my way of doing and analysing? Is it a bug and if so, will it be fixed soon?
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    6,205
    Im not aware of any bugs that fit this description, so if it is a bug it has not yet been reported.
    Can you share an example project with the issue?
     
  3. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    51
    Thank you for your quick answer!

    I dit try to make a repro as quick as possible.

    In
    UpdateMilestoneComponent.cs
    I did comment some part of the code to go back to the initial code [that I suppose should work as is]

    If you uncomment you reach the "post workaround" state with the crash when you exit "play mode"

    Code (CSharp):
    1.     private void Update()
    2.     {
    3.         _milestonePopulationCountLocalisedVariable.Value = Time.frameCount;
    4.         _milestonePopulationLevelLocalisedVariable.Value = Time.renderedFrameCount;
    5.  
    6.         // if (_milestoneText!= null)
    7.         // {
    8.         //     _milestoneText.RefreshString();
    9.         // }
    10.     }
    11.  


    My game if someone want to test :D https://store.steampowered.com/app/1694260/Moons_of_Ardan/
     

    Attached Files:

  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    6,205
    hadesfury likes this.
  5. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    6,205
    I took a look at the project. It is indeed a bug, we were not triggering an update from nested strings.
    A fix is in review now for the next release.
    I have also fixed the MissingReferenceException bug.

    Here is a small improvement to your code.
    Code (csharp):
    1. private void Update()
    2. {
    3.     PersistentVariablesSource.BeginUpdating();
    4.     _milestonePopulationCountLocalisedVariable.Value = Time.frameCount;
    5.     _milestonePopulationLevelLocalisedVariable.Value = Time.renderedFrameCount;
    6.     PersistentVariablesSource.EndUpdating();
    7. }
    This ensures that only 1 refresh is made to the string instead of 1 per change.
     
    Last edited: Oct 8, 2021
    hadesfury likes this.
  6. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    51
    Thank you so much .. the update has been released from your side "1.0.4" but also, the "Updating" thing will help to improve some perfs
     
    karl_jones likes this.
unityunity