Search Unity

How can I assign localized string component to the property of other gameobject in editor?

Discussion in 'Localization Tools' started by unace, Feb 10, 2020.

  1. unace

    unace

    Joined:
    Oct 13, 2014
    Posts:
    23
    Hi
    I am very excited you're making localization tools! thank you.
    I'd like to use a localized string component as property however I can't find how to assign a gameobject to it in editor. Could you help me?

    Code (CSharp):
    1. public class LoadingUI : MonoBehaviour
    2.     {
    3.         [SerializeField]
    4.         private GameObject loading = null;
    5.  
    6.         [SerializeField]
    7.         private LocalizedString statusText = null;
    8.  
    9.         private void Awake()
    10.         {
    11.             loading.SetActive(true);
    12.         }
    13.  
    14.         public void Hide()
    15.         {
    16.             loading.SetActive(false);
    17.         }
    18.  
    19.         public void SetStatusName(string status)
    20.         {
    21.             statusText.SetReference("UIText", status);
    22.         }
    23.     }
    upload_2020-2-9_23-46-34.png
    Can't drag and drop a gameobject to this property.

    I know there is a workaround like below, but I want to use it directly.

    Code (CSharp):
    1. public class LoadingUI : MonoBehaviour
    2.     {
    3.         [SerializeField]
    4.         private GameObject loading = null;
    5.  
    6.         [SerializeField]
    7.         private GameObject statusText = null;
    8.  
    9.         private void Awake()
    10.         {
    11.             loading.SetActive(true);
    12.         }
    13.  
    14.         public void Hide()
    15.         {
    16.             loading.SetActive(false);
    17.         }
    18.  
    19.         public void SetStatusName(string status)
    20.         {
    21.             statusText.GetComponent<LocalizedString>().SetReference("UIText", status);
    22.         }
    23.     }
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    Hi,
    The LocalizedString does not link directly to any GameObjects. Its for providing the localized string, you then need to assign that to your StatusText.
    I suggest you look at the LocalizeStringBehaviour. This is a Component you can use to hook up a GameObject, such as UI Text or TMP.
    If you click the context menu on the Text you will see a Localize option which will add it and set it up automatically for you.
    https://docs.unity3d.com/Packages/com.unity.localization@0.6/manual/ComponentLocalizers.html

    You can also look at the source for a guide to doing it yourself

    Code (csharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine.Events;
    4. using UnityEngine.Localization.Tables;
    5.  
    6. namespace UnityEngine.Localization.Components
    7. {
    8.     /// <summary>
    9.     /// Component that can be used to Localize a string.
    10.     /// Allows for configuring optional string arguments and provides an update event that can be used to update the string.
    11.     /// </summary>
    12.     [AddComponentMenu("Localization/Localize String")]
    13.     public class LocalizeStringBehaviour : MonoBehaviour
    14.     {
    15.         /// <summary>
    16.         /// UnityEvent which can pass a string as an argument.
    17.         /// </summary>
    18.         [Serializable]
    19.         public class StringUnityEvent : UnityEvent<string> {};
    20.  
    21.         [SerializeField]
    22.         LocalizedString m_StringReference = new LocalizedString();
    23.  
    24.         [SerializeField]
    25.         List<Object> m_FormatArguments = new List<Object>();
    26.  
    27.         [SerializeField]
    28.         StringUnityEvent m_UpdateString = new StringUnityEvent();
    29.  
    30.         /// <summary>
    31.         /// References the <see cref="StringTable"/> and <see cref="StringTableEntry"/> of the localized string.
    32.         /// </summary>
    33.         public LocalizedString StringReference
    34.         {
    35.             get => m_StringReference;
    36.             set => m_StringReference = value;
    37.         }
    38.  
    39.         /// <summary>
    40.         /// Event that will be sent when the localized string is ready.
    41.         /// </summary>
    42.         public StringUnityEvent OnUpdateString
    43.         {
    44.             get => m_UpdateString;
    45.             set => m_UpdateString = value;
    46.         }
    47.  
    48.         /// <summary>
    49.         /// Starts listening for changes to <see cref="StringReference"/>.
    50.         /// </summary>
    51.         protected virtual void OnEnable()
    52.         {
    53.             if (m_FormatArguments.Count > 0)
    54.             {
    55.                 StringReference.Arguments = m_FormatArguments.ToArray();
    56.             }
    57.  
    58.             StringReference.RegisterChangeHandler(UpdateString);
    59.         }
    60.  
    61.         /// <summary>
    62.         /// Stops listening for changes to <see cref="StringReference"/>.
    63.         /// </summary>
    64.         protected virtual void OnDisable()
    65.         {
    66.             StringReference.ClearChangeHandler();
    67.         }
    68.  
    69.         /// <summary>
    70.         /// Invokes the <see cref="OnUpdateString"/> event.
    71.         /// </summary>
    72.         /// <param name="value"></param>
    73.         protected virtual void UpdateString(string value)
    74.         {
    75.             OnUpdateString.Invoke(value);
    76.         }
    77.     }
    78. }
     
  3. unace

    unace

    Joined:
    Oct 13, 2014
    Posts:
    23
    Hi Karl,
    Thanks for the reply, but I think I didn't fully describe my case.

    I already added LocalizeStringBehaviour component via "Localise" context menu to a gameobject that has a text component. Let say this gameobject "StatusText".
    And I added my Loading UI component to another gameobject, "LoadingUI".
    I want to assign "StatusText" to the statusText property of "LoadingUI" gameobject in editor. I tried to drag and drop it but it doesn't work.

    upload_2020-2-10_22-30-0.png

    I attached the sample project for this. View attachment localize.zip
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    OK I think I understand. You want to reference the LocalizedString in another script.
    A LocalizedString is just a normal class so you can't reference it in the way you want however the LocalizeStringBehaviour is a MonoBehaviour and can be referenced like this.

    So the following will work

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.Localization.Components;
    4.  
    5. public class LoadingUI : MonoBehaviour
    6. {
    7.     [SerializeField]
    8.     LocalizeStringBehaviour statusTextBehaviour;
    9.  
    10.     public void SetStatusName(string status)
    11.     {
    12.         statusTextBehaviour.StringReference.SetReference("UIText", status);
    13.     }
    14. }
     
    emredesu and ayhanavci like this.
  5. unace

    unace

    Joined:
    Oct 13, 2014
    Posts:
    23
    karl_jones likes this.
  6. TheCaveOfWonders

    TheCaveOfWonders

    Joined:
    Mar 2, 2014
    Posts:
    27
    I can't seem to find LocalizeStringBehaviour anymore in the latest version of localization package, was that replaced by something or renamed?
     
    Last edited: Apr 22, 2023
  7. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    It was renamed to LocalizeStringEvent.
    What version of the package are you using, that was a long time ago. We are on 1.4.3 now. If it's not visible in the package manager you can manually edit the manifest.json file in the Packages folder.
     
  8. TheCaveOfWonders

    TheCaveOfWonders

    Joined:
    Mar 2, 2014
    Posts:
    27
    Thank for the quick response, I'm on v1.4.3.

    Perhaps I misunderstood the use case described by OP, I have a LocalizedString in a scriptableObject, and I would like to reference it in another scriptableObject; the reason being is it's a smart LocalizedString and is using local variables, so I'm trying to avoid having to redo that work in my 2nd scriptableObject.

    I can't drag and drop anything in the LocalizeStringEvent field, am I doing it wrong or did I misunderstand the use case here?

    My current workaround is to have a reference of the scriptableObject and use that when returning the LocalizedString.

    Code (CSharp):
    1. [SerializeField]
    2. private LocalizedString _name;
    3. public LocalizedString Name => _myScriptableObject?.Name ?? _name;
    4.  
    5. [SerializeField]
    6. private ScriptableObject _myScriptableObject;
     
    Last edited: Apr 22, 2023
  9. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,282
    A LocalizedString is not a unity object so can't be referenced across objects though the inspector, what you are doing is fine though.
     
    TheCaveOfWonders likes this.