Nested LocalizedString does not refresh

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.

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

In my update function, I just do the following

_milestonePopulationCountLocalisedVariable.Value = nextMilestoneInfo._populationCount;
_milestonePopulationLevelLocalisedVariable.Value = nextMilestoneInfo._populationLevel;

those two variables are assigned in my Start function from a reference assigned in the editor “MilestoneText” in the image

[SerializeField] private LocalizeStringEvent _milestoneText;

private LocalizedString _nextMilestoneLocalizedString;
private IntVariable _milestonePopulationCountLocalisedVariable;
private IntVariable _milestonePopulationLevelLocalisedVariable;

private void Start()
{
    _nextMilestoneLocalizedString = _milestoneText.StringReference["_nextMilestone"] as LocalizedString;
    _milestonePopulationCountLocalisedVariable = _nextMilestoneLocalizedString["_populationCount"] as IntVariable;
    _milestonePopulationLevelLocalisedVariable = _nextMilestoneLocalizedString["_populationLevel"] as IntVariable;
}

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

Exception: Reentering the Update method is not allowed.  This can happen when calling WaitForCompletion on an operation while inside of a callback.
UnityEngine.ResourceManagement.ResourceManager.Update (System.Single unscaledDeltaTime) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/ResourceManager.cs:1067)
UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle`1[TObject].WaitForCompletion () (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/AsyncOperations/AsyncOperationHandle.cs:194)
UnityEngine.Localization.LocalizedString.GetLocalizedString () (at Library/PackageCache/com.unity.localization@1.0.3/Runtime/Localized Reference/LocalizedString.cs:249)
Pandora.Managers.GameManager.SendMessageEvent (Pandora.Events.GameEvent gameEvent) (at Assets/Pandora/Scripts/Managers/GameManager.cs:914)
Pandora.Managers.EventManager.TriggerEvent[TYPE_EVENT] (TYPE_EVENT gameEvent) (at Assets/Pandora/Scripts/Managers/EventManager.cs:90)
Pandora.Managers.SaveManager.SaveFileContent (Pandora.SaveData saveData, System.String saveName) (at Assets/Pandora/Scripts/Managers/SaveManager.cs:241)
Pandora.Managers.LoadingManager.ApplicationOnLogMessageReceived (System.String condition, System.String stacktrace, UnityEngine.LogType type) (at Assets/Pandora/Scripts/Managers/LoadingManager.cs:59)
UnityEngine.Application.CallLogCallback (System.String logString, System.String stackTrace, UnityEngine.LogType type, System.Boolean invokedOnMainThread) (at <ca496b8c93454b2f9b9924292c19379f>:0)
UnityEngine.Debug:LogException(Exception)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/Util/DelegateList.cs:73)
UnityEngine.Localization.Components.LocalizeStringEvent:RefreshString()
Pandora.Ui.IngameUiLayout:Update() (at Assets/Pandora/Scripts/Ui/IngameUiLayout.cs:368)
MissingReferenceException: The object of type 'LocalizationBehaviour' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.MonoBehaviour.StartCoroutine (System.Collections.IEnumerator routine) (at <ca496b8c93454b2f9b9924292c19379f>:0)
UnityEngine.Localization.LocalizationBehaviour.ReleaseNextFrame (UnityEngine.ResourceManagement.AsyncOperations.AsyncOperationHandle handle) (at Library/PackageCache/com.unity.localization@1.0.3/Runtime/Utilities/LocalizationBehaviour.cs:29)
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)
DelegateList`1[T].Invoke (T res) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/Util/DelegateList.cs:69)
UnityEngine.Debug:LogException(Exception)
DelegateList`1:Invoke(AsyncOperationHandle`1) (at Library/PackageCache/com.unity.addressables@1.19.4/Runtime/ResourceManager/Util/DelegateList.cs:73)
UnityEngine.Localization.Components.LocalizeStringEvent:RefreshString()
Pandora.Ui.IngameUiLayout:Update() (at Assets/Pandora/Scripts/Ui/IngameUiLayout.cs:368)

So second workaround to avoid that and sorry it is ugly but it prevents the crash as my values are not changing that often.

if ((_milestonePopulationCountLocalisedVariable.Value != nextMilestoneInfo._populationCount) || (_milestonePopulationLevelLocalisedVariable.Value != nextMilestoneInfo._populationLevel))
{
    _milestonePopulationCountLocalisedVariable.Value = nextMilestoneInfo._populationCount;
    _milestonePopulationLevelLocalisedVariable.Value = nextMilestoneInfo._populationLevel;
    _milestoneText.RefreshString();
}

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?

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?

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”

    private void Update()
    {
        _milestonePopulationCountLocalisedVariable.Value = Time.frameCount;
        _milestonePopulationLevelLocalisedVariable.Value = Time.renderedFrameCount;

        // if (_milestoneText!= null)
        // {
        //     _milestoneText.RefreshString();
        // }
    }

My game if someone want to test :smile: Moons of Ardan on Steam

7551547–933586–LocalizationBugReport.rar|attachment (1.08 MB)

Thanks that shows the problem. I don’t have time to dig into it right now but I have created a bug report so it will be looked at.

The URL may not work at the moment, the system takes a little time to update.

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.

private void Update()
{
    PersistentVariablesSource.BeginUpdating();
    _milestonePopulationCountLocalisedVariable.Value = Time.frameCount;
    _milestonePopulationLevelLocalisedVariable.Value = Time.renderedFrameCount;
    PersistentVariablesSource.EndUpdating();
}

This ensures that only 1 refresh is made to the string instead of 1 per change.

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