Search Unity

Bug Manually adding Variable to LocalizedString doesn’t make them refresh when modified?

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

  1. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    Hello,

    using this type of Smart String
    I decided not to define variables in the inspector but in the
    Start
    function like this:
    Code (CSharp):
    1. private void Start()
    2. {
    3.     _controlsText.StringReference.Add("_cameraDownKey", _cameraDownKeyLocalisationVariable);
    4.     _cameraLeftKeyLocalisationVariable = new StringVariable {Value = Keyboard.current[Key.A].displayName};
    5.     _cameraRightKeyLocalisationVariable = new StringVariable {Value = Keyboard.current[Key.D].displayName};
    6.     _controlsText.StringReference.Add("_cameraRightKey", _cameraRightKeyLocalisationVariable);
    7. }
    And to update it in
    Update 
    function:
    Code (CSharp):
    1. private void Update()
    2. {
    3.     PersistentVariablesSource.BeginUpdating();
    4.     _cameraLeftKeyLocalisationVariable.Value = Keyboard.current[Key.A].displayName;
    5.     _cameraRightKeyLocalisationVariable.Value = Keyboard.current[Key.D].displayName;
    6.     PersistentVariablesSource.EndUpdating();
    7. }
    BUT it does not make my
    controlText
    refresh when I do

    I have to manually call
    _controlsText.StringReference.RefreshString();
    to force the refresh

    I will probably change my system, but I was curious to know if this was expected.
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Is the value you are assigning different? We only update if the value changes so if the displayName is still the same then a refresh wont occur.
     
  3. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    Yes, I double-checked, the value changes each time I switch my keyboard layout, and it does not update visually.
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Can you please file a bug report? I'll need to take a closer look and see what's going on.
     
  5. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    You were probably right, it is most probably related to the nature of
    Keyboard.current[Key.A].displayName;
    that is a C# property with an internal string behind.
    I tried to reproduce it with a simple string and it works. Do you want me to go further and integrate the "new input system" in my repro project to replicate the behaviour or does it already make sense now ?

    Code (CSharp):
    1.         public string displayName
    2.         {
    3.             get
    4.             {
    5.                 RefreshConfigurationIfNeeded();
    6.                 if (m_DisplayName != null)
    7.                     return m_DisplayName;
    8.                 if (m_DisplayNameFromLayout != null)
    9.                     return m_DisplayNameFromLayout;
    10.                 return m_Name;
    11.             }
    12.             // This is not public as a domain reload will wipe the change. This should really
    13.             // come from the control itself *if* the control wants to have a custom display name
    14.             // not driven by its layout.
    15.             protected set => m_DisplayName = value;
    16.         }
    Code (CSharp):
    1. internal string m_DisplayName; // Display name set by the control itself (may be null).
     
  6. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    Unexpectedly, it works in the repro project with the new Input System .. so I am hintless.
     
  7. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    I checked a bit more .. what is interesting is that it does not seem related to the update of the "variable" but the placeholder does not seem to be updated at all by the localization system.
    upload_2021-11-6_12-45-58.png
     
  8. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Thats strange. Is there maybe a duplicate placeholder class?
    Try doing (_controlsText.StringReference["_cameraDownKey"] as StringVariable).Value = ...
     
  9. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    No it does not work.

    If I call
    _controlsText.StringReference.RefreshString();
    in the Start function it starts to work too.

    It is a LocalizedStringEvent nested in an instanced "root" Canvas but replicating this behaviour in my "repro" project does not work :(. I think I have to let it down, but I you have any idea or things you want to test, I will try to be as reactive as possible.
     
  10. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Oh a nested localized string? I did fix a bug with it not updating recently, it is available in 1.0.4.
    What version are you using?
     
  11. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    I am using 1.0.5 to be sure that it wasn’t fixed.
    What I mean by nested, was misleading, and just meant it was into a child of a root canvas. Sorry.
     
  12. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Ah. You could try adding a callback to the value changed event for the properties and see if they are being sent when you change the value.
    Also try without the begin and end change part.
     
  13. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    I have already tried without "begin/end" part, but tested it again with no success.

    Code (CSharp):
    1.             _cameraUpKeyLocalisationVariable.ValueChanged += CameraUpKeyLocalisationVariableOnValueChanged;
    2.             _controlsText.StringReference.ValueChanged += StringReferenceOnValueChanged;
    3.         }
    4.  
    5.         private void StringReferenceOnValueChanged(IVariable obj)
    6.         {
    7.             Debug.Log("StringReferenceOnValueChanged is called");
    8.         }
    9.  
    10.         private void CameraUpKeyLocalisationVariableOnValueChanged(IVariable obj)
    11.         {
    12.             Debug.Log("CameraUpKeyLocalisationVariableOnValueChanged is called");
    13.         }
    Added those line, only "CameraUpKeyLocalisationVariableOnValueChanged" is called.
     
  14. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Does the initial string use the variable? We only subscribe to variables that are used to generate the last string, so if you add a variable or change one that was not actually used then it won't trigger a refresh. It could be that we update the string first, you then update the variables and so the new variables dont trigger the update because they were not used the first time.
    Are you able to share the project?
     
  15. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    I am not sure I got your last statement :/ really sorry. What do you mean by the "initial string"?

    I can’t share the project otherwise it would have already been done. We can try to do some kind of "code review" using "video" on discord for example. I don’t know if it is something you do.
     
  16. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    I mean when it first generates the Localized String in Start it could be that there is no value being returned by the properties(they look blank in the original screenshot). Try enabling errors for the smart format strings, maybe they are being ignored at the moment
    upload_2021-11-8_11-47-46.png

    I could probably do a zoom call to take a look.
     
  17. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    upload_2021-11-8_13-32-38.png

    There is an error thrown when I activate the setting you asked me to. But it did not make much sense to me :D
    Does it mean that as long as it is a smart string, if you did not define parameters, it will "crash" the system?
     
  18. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    It was probably on "ignore" setting because I use the package for a long time.
     
  19. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Yes if you have a placeholder that could not be evaluated then it will either throw an error or ignore it. That's why it doesn't trigger the update because it didn't use the persistent variable. One way to solve this would be to have the localized string event disabled, then enable it after you have initialized in your start method.
     
  20. hadesfury

    hadesfury

    Joined:
    Jan 23, 2014
    Posts:
    55
    Sure, or we can just call
    RefreshString
    at the end of the
    Start
    function.

    Anyway thank you for your time. As I told you, I won’t use that way of doing and now that we found that it is not a bug, I will just remove all those codes.
     
    karl_jones likes this.