# Localization

### Enabling Game Localization

1. Select the **Game Localization** component in the **GAMEMANAGER** object.
2. Click the **Enable GLoc Localization** button.

<figure><img src="/files/3B2q2PeYBnLECS2gqk8l" alt=""><figcaption></figcaption></figure>

{% hint style="danger" %}
If localization is enabled, you can use **GString** in place of a standard **string** to automatically localize text.

However, if you choose not to use localization, **GString** will still function, but it will behave like a regular **string** field, displaying the text as-is without attempting to fetch a localized value.
{% endhint %}

### Adding New Localization Strings

1. You can either open the default **Game Localization Table** asset or create a new one:
   * To **create a new table**, right-click in your desired folder and select:\
     \&#xNAN;**`Create → UHFPS → Localization → Localization Table`**
   * To **edit the existing table**, navigate to:\
     \&#xNAN;**`UHFPS → Scriptables → Game → Localization`**, then select **`GameLocalizationTable`**.
2. To open the Localization Editor, simply select the **GameLocalizationTable** asset and click **Open Localization Editor**.

<figure><img src="/files/54KNumFN7L7xLXWgsEsH" alt=""><figcaption></figcaption></figure>

3. Select an existing language or create a new one by clicking the **+** button next to the **LANGUAGES** title.

<figure><img src="/files/OGkP5g7LmkXKlGlqCBrR" alt=""><figcaption></figcaption></figure>

4. Before adding localization strings, you must assign a **Language Asset**. You can either create a new one by clicking the **Create Asset** button or assign an existing asset if one is already available.

<figure><img src="/files/ZxGxC1dNllQs3SKuU7kC" alt=""><figcaption></figcaption></figure>

5. To add a new table sheet section, click the **+** button next to the **TABLE SHEET** title. You can name the section however you like, but it's recommended to use **CamelCase** or **snake\_case** for naming sections and entries to maintain consistency and readability.

{% embed url="<https://lokalise.com/blog/translation-keys-naming-and-organizing/>" %}

<figure><img src="/files/8tPZpDoNhTGkAiHfpabT" alt=""><figcaption></figcaption></figure>

6. To add a new section entry, right-click the section and select **Add Entry**.

<figure><img src="/files/EWjiRHGUotoHfL0w6FUf" alt=""><figcaption></figcaption></figure>

7. To start defining localization strings, select the desired language, this will open the **Language Editor**. From there, you can enter translations for each string in the selected language.

<figure><img src="/files/RPYkwT6igoHb87AZjMZZ" alt=""><figcaption></figcaption></figure>

8. Once you’ve finished defining the translations for your languages, simply click **Save Asset** to store your changes.
9. If you’ve created a new localization table, make sure to assign it to the **Game Localization** component by setting it in the **Localization Table** field.

### Using Localization Keys

1. In order to utilize localized strings, use the **GString** instead of **String** in your scripts when creating a string field.

```csharp
using UnityEngine;
using UHFPS.Runtime;

public class Example : MonoBehaviour
{
    public GString SomeText;
}
```

<figure><img src="/files/XFvG01vjtLJ51SswpsR5" alt=""><figcaption></figcaption></figure>

4. To listen for localization or input changes, you need to subscribe to them. To accomplish this, simply write a subscribe method within the **Start** function.

```csharp
using UnityEngine;
using UHFPS.Runtime;

public class Example : MonoBehaviour
{
    public GString SomeText;

    private void Start()
    {
        SomeText.SubscribeGloc();
    }
}
```

{% hint style="info" %}
If you want to update a UI text dynamically when the localization changes, for example, updating labels or buttons, you can do this by writing a custom action using the `onUpdate` parameter within the `SubscribeGloc()` method. This allows you to define what should happen whenever the localized text updates.
{% endhint %}

```csharp
using UnityEngine;
using UHFPS.Runtime;
using TMPro;

public class Example : MonoBehaviour
{
    public GString SomeText;
    public TMP_Text UIText;

    private void Start()
    {
        SomeText.SubscribeGloc(text => UIText.text = text);
    }
}
```

{% hint style="info" %}
You can also subscribe to input-related localization updates using the `SubscribeGlocMany()` method. However, this requires you to define the input you want to listen for in the **GameLocalizationTable** asset using the `"[action] Text"` format.

The `[action]` tag will automatically be converted to a `<sprite=0>` format, which enables icon display within the text. You can customize these icons through the **Input Sprites Asset**, which is a **TMP\_Sprite Asset** used by TextMesh Pro to manage and render input icons.
{% endhint %}

<figure><img src="/files/DLGtx04RoWFRImHaSNv1" alt=""><figcaption></figcaption></figure>

```csharp
using UnityEngine;
using UHFPS.Runtime;
using TMPro;

public class Test : MonoBehaviour
{
    public GString SomeText;
    public TMP_Text UIText;

    private void Start()
    {
        SomeText.SubscribeGlocMany(text => UIText.text = text);
    }
}
```

5. Finally, select the desired localization key by clicking the **magnifying glass** icon located on the right side of the string field. This will open a list of available keys to choose from.

<figure><img src="/files/JPrOELcN7oZzfRCO4UJK" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
If you need to subscribe to listen for changes in an alternative manner, you can take look at the the static **GameLocalizationE** class, which contains all the necessary subscribe methods. This class can be found within the **GameLocalization** script.
{% endhint %}

{% hint style="danger" %}
Keep in mind that these methods are dependent on **GameLocalization**. If localization is disabled, they will no longer function.
{% endhint %}

{% hint style="info" %}
As mentioned in other guides, you can bypass the default localization behavior by placing an asterisk (`*`) at the beginning of a localization string. This tells the system to treat the key as the actual text itself, rather than looking it up in the localization table.
{% endhint %}

### Exporting/Importing CSV

1. First, define all the languages you intend to support. For example, in my case, I added **German** to the list of languages, without providing translations for the localization strings.

<figure><img src="/files/RlmBfoOo0CJadqQnUJFw" alt=""><figcaption></figcaption></figure>

2. Click **Export CSV** and save the file to your desired location.

{% hint style="info" %}
The localization table will be exported in the following CSV format:

`Key , Language1 , Language2 , Language3`

Each row represents a localization entry, with the key followed by its translations in each defined language.
{% endhint %}

<figure><img src="/files/TfEH9kdOSKDht8JEp0fo" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
You can either use an **AI translation tool** to automatically translate all texts into the desired language, or you can **open the CSV file in a CSV editor** (like Excel, Google Sheets, or a text editor) and manually translate the texts yourself.
{% endhint %}

3. Once you've finished translating all the texts, click **Import CSV** and select the CSV file containing your translations. This will update the localization table with the newly translated strings.

<figure><img src="/files/S4tywTDZpcPuSUAo2tvy" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.twgamesdev.com/uhfps/guides/localization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
