Forum rules - please read before posting.

Custom Translatables / Text Gathering Issue

We recently started looking into using custom translatables to gather text from some specialized UI game objects in our game, i.e. they have a script component attached to them that implements the ITranslatable interface. The objects; however, aren't in the scene initially, i.e. they are prefabs that get dynamically instantiated into the scene via an action list script.

We noticed 2 issues:

1.) The speech manager text gathering tool didn't gather the text from these dynamically loaded objects and we had to explicitly put instances of them in the scene ahead of time before the text gathering tool recognized them. Is there something else we need to do in order for these dynamically loaded objects text to be recognized? Ideally we'd want these objects to continue to be dynamically loaded via the Action List script as we have additional logic in these scripts that determine which objects to load (i.e. we wont always necessarily want these objects to load into this scene)

2.) When the text was gathered, there was no way to view the gathered text from these objects from within the speech manager menu (i.e. none of the filters allowed it to display). Once we exported text though the lines from these objects did show up in the exported spread sheet. We set the text type to be either Speech or Custom but either way nothing allowed the gathered text to be filterable in the speech manager menu

Any insight or tips you might be able to provide would be greatly appreciated


  • The speech manager text gathering tool didn't gather the text from these dynamically loaded objects and we had to explicitly put instances of them in the scene ahead of time before the text gathering tool recognized them.

    When AC gathers up your game text via the Speech Manager, it searches all AC objects and scenes for references made to anything translatable.

    It'll be smart enough to follow links to e.g. ActionLists referenced by other ActionLists, but in a few cases (such as referencing an object through script, or as a prefab in the "Object: Animate" Action, it won't be able to follow such references.

    If you want to be able to translate an object you spawn only at runtime, it's best to place it in the scene - as you've done - and then any apply changes to the instance back to the prefab once the "Gather text" operation has finished.

    However, this needn't mean the object itself can't be spawned - this is just for the duration of the "Gather text" operation. What you can do is create a new scene that only contains such prefabs, add it to your Build Settings, but then never visit it in-game. The Speech Manager will search it, gather up text it finds, and so long as you then apply changes back to the prefab, the prefab's internal text IDs should still match those generated by the process.

    When the text was gathered, there was no way to view the gathered text from these objects from within the speech manager menu

    Odd. AC's not explicitly aware of what counts as "custom" text vs built-in text, so how things get filtered should be purely down to the implemenation. If you'd like to share your custom ITranslatable implentation, I can take a look see if anything amiss stands out.

  • Thanks for the tips. Here's the script component that we attach to our prefab objects:

    public class TutorialText : MonoBehaviour, ITranslatable

    /** This is the text we'll make available for translation */
    public string text;
    /** This is the ID number our translatable text will be assigned */
    public int lineID = -1;
    public string GetTranslatableString (int index)
        // Return the text to be translated
        return text;
    public int GetTranslationID (int index)
        // Return the integer variable used to store the translation ID
        return lineID;
    /** Note: These functions are placed in UNITY_EDITOR as they only need accessing from within the Speech Manager, outside of runtime */
    public void UpdateTranslatableString (int index, string updatedText)
        // Update the original text
        text = updatedText;
    public int GetNumTranslatables ()
        // Return 1 unless you want to store multiple translatable texts in a single script.
        return 1;
    public bool CanTranslate (int index)
        // Check if the text is OK to be translated (usually just IsNullOrEmpty on the string will do, but sometimes it'll depend on other options)
        return !string.IsNullOrEmpty (text);
    public bool HasExistingTranslation (int index)
        // Basically check if the ID number > -1, since this is what happens when a translation is recorded
        return (lineID >= 0);
    public void SetTranslationID (int index, int lineID)
        // Set the translation ID variable
        this.lineID = lineID;
    public string GetOwner (int index)
        // This is normally string.Empty, as it's mainly used for speech lines and menu elements
        return "My Owner";
    public bool OwnerIsPlayer (int index)
        // This is normally false, as it's mainly used for speech lines
        return false;
    public AC_TextType GetTranslationType (int index)
        // Return the type of translation, for sorting within the Speech Manager
        return AC_TextType.Speech; //I tried setting this to Custom but it still doesn't show up in speech manager 


  • As you made a local scene instance of it for it to be gathered up, it should be listed as Speech inside that scene.

    If it's not appearing, PM me your Speech Manager, the CSV export, as well as details of a typical line to search for - I'll see if I can spot the issue.

  • edited February 2021

    Ok I believe we figured out why we weren't seeing the gathered text for our custom objects. We didn't have the Scene Filter option set properly, i.e. we had it set to No Scene. Once we set the filter to Any or No Scene we were able to see the gathered text in the speech manager for all speech text. I'm guessing the other lines of speech text were showing for us because they were coming from the Play Speech events in our dynamically loaded Action Lists (ie the Action List scripts that weren't in any scene initially).

    It's also worth noting that our scene filter list was empty up until yesterday. Once we followed one of your tips and created a dummy scene to dump instances of our custom prefabs into (i.e. the objects that we wanted text gathered from), that particular scene started showing up in the Scene Filter option list.

    Just out of curiosity, because you had mentioned that that the text gathering utility is designed to gather text from AC objects, ActionLists, and AC-objects/other-actionlists referenced in ActionLists, etc... Would it be possible (as maybe another trick/workaround) to fake it and make our dynamically loaded custom objects/prefabs actual AC objects? What exactly constitutes an object as being an AC Object? i.e. if I just slapped an AC component onto our custom objects/prefabs (i.e. an empty hotspot, empty NPC/Player component, etc...) would the system end up considering the referenced prefab from our ActionList as an AC object and gather the text from it?

  • It's not so much a case of them needing to have AC components, but more to do with the fact that only assets with direct references are searched. While the operation could feasibly search all assets within a Project, it's safer not to - so as to avoid including old/unused/demo assets.

    Things aren't so strict when it comes to scenes, however. If an ITranslatable is found in a scene listed in the Build Settings, AC considers it safe for inclusion.

    Though, it may be appropriate for prefabs referenced in the Object: Add or remove Action to be considered safe as well. Is this how you currently spawn in your prefab?

  • edited February 2021

    Yes, i.e. for the particular dynamically instantiated prefabs with the text that we want translatable, they are currently spawned in via the Object Add or remove Action List event

    The bigger picture workflow design/strategy we were thinking was we were going to have a handful of scenes to load, but we wanted to reuse the scenes and have various Action List scripts drive and dynamically load in certain pieces of entities depending on where you were story-wise in our visual novel / adventure game. Basically this because you're going to be back-tracking a lot during the game (i.e. open world / RPG / Metroidvania style)

    I suppose the alternative is just duplicate the scenes with the similar art backgrounds and then just place all the appropriate entities depending on game state/progression but that seems cumbersome and inefficient? I would assume its a better practice not to have lots and lots of scenes (especially if most of them contain all the same static art back drop and will have minor differences as far as the dynamic entities)

    Or we could just keep one scene and place every single possible dynamic object that the overall game is going to have and use the scripts to turn on/off the objects depending on game state/flow. I suppose this would be the 2nd best alternative

  • I don't see an issue with your original idea - have multiple scenes, but re-use them where it makes sense to.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.