Hi, first of all, I want you to know that I'm using a translator, so my sentences can sometimes be vague because of this. If you don't understand something, please feel free to ask questions!
I'm making a point-and-click game with adventure creator. The game has an unusual hint system that uses labels on hotspots.
Clicking on a character prints the hotspot's label in the specified area. These labels are stored in the CharManager as a List named labelist.
While the other elements of the game could be solved with adventure creator's basic translation system, the labellist required the use of a custom itranslatable. I wrote the following code in CharManager.
I use a format that stores characters as prefabs and loads them dynamically in-game. To use gather text, I created a scene that was included in the build but not accessible, and put all the prefabs into it to make gather text work.
using AC;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharManager : MonoBehaviour, ITranslatable
{
public List<string> labellist;
private int[] labelListID = new int[] { -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10, -10};
/** ITranslatable implementation */
public string GetTranslatableString(int index)
{
return labellist[index];
}
public int GetTranslationID(int index)
{
return labelListID[index];
}
public int GetNumTranslatables()
{
return labellist.Count;
}
public bool CanTranslate(int index)
{
return !string.IsNullOrEmpty(labellist[index]);
}
public bool HasExistingTranslation(int index)
{
return (labelListID[index] >= -1);
}
public void SetTranslationID(int index, int lineID)
{
labelListID[index] = lineID;
}
public string GetOwner()
{
return string.Empty;
}
public bool OwnerIsPlayer()
{
return false;
}
public AC_TextType GetTranslationType(int index)
{
return AC_TextType.Hotspot;
}
public void UpdateTranslatableString(int index, string updatedText)
{
Debug.Log($"Updating translation for index {index}: {updatedText}");
labellist[index] = updatedText;
return;
}
public string GetOwner(int index)
{
return "null";
}
public bool OwnerIsPlayer(int index)
{
return true;
}
}
As a result, the text in the labellist was collected by gather text just fine, and when I did an export csv, it was output correctly (but only when set to any or no scene).
However, when I run the game, only labellist is not translated correctly.
Cannot find translation for '(content of text)' because the text has not been added to the Speech Manager.
-> AC debug logger
UnityEngine.Debug:Log (object,UnityEngine.Object)
AC.ACDebug:Log (object,UnityEngine.Object) (at Assets/AdventureCreator/Scripts/Static/ACDebug.cs:20)
AC.RuntimeLanguages:GetTranslation (string,int,int,int) (at Assets/AdventureCreator/Scripts/Speech/RuntimeLanguages.cs:303)
AC.RuntimeLanguages:GetTranslation (string,int,int,int,AC.AC_TextType) (at Assets/AdventureCreator/Scripts/Speech/RuntimeLanguages.cs:377)
AC.MenuElement:UpdateLabel (int) (at Assets/AdventureCreator/Scripts/Menu/Menu classes/MenuElement.cs:367)
AC.MenuElement:TranslateLabel (int) (at Assets/AdventureCreator/Scripts/Menu/Menu classes/MenuElement.cs:391)
AC.MenuLabel:UpdateLabelText (int) (at Assets/AdventureCreator/Scripts/Menu/Menu classes/MenuLabel.cs:453)
AC.MenuLabel:PreDisplay (int,int,bool) (at Assets/AdventureCreator/Scripts/Menu/Menu classes/MenuLabel.cs:422)
AC.PlayerMenus:UpdateElements (AC.Menu,int,bool) (at Assets/AdventureCreator/Scripts/Controls/PlayerMenus.cs:1585)
AC.PlayerMenus:UpdateMenu (AC.Menu,int,bool,bool) (at Assets/AdventureCreator/Scripts/Controls/PlayerMenus.cs:1543)
AC.PlayerMenus:UpdateAllMenus() (at Assets/AdventureCreator/Scripts/Controls/PlayerMenus.cs:2158)
AC.StateHandler:Update () (at Assets/AdventureCreator/Scripts/Game engine/StateHandler.cs:243)
I get an error saying
This is strange, because in the speech manager the text in the labellist looks fine, and the translation is entered correctly.
Just in case, I even put the code Debug.Log($"Updating translation for index {index}: {updatedText}"); in the UpdateTranslatableString function, but it doesn't print.
What should I do and where is the problem? Any help would be greatly appreciated!
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
Welcome to the community, @arrokoth.
It looks to be due to the labelListID array not being serializable - which means any changes made to it won't be saved.
Making this public may be enough, but I'd recommend storing both the text and the ID within its own class so that they always have the same array size. Something like this:
First of all, thank you for your answer, kind people like you always help newbie programmers!
I've tried rewriting the code as you said, but I'm having the same problem. The interesting point is that the ID of the CSV file starts at -1.
public bool HasExistingTranslation(int index) => (labelDatas[index].ID >= -1);
I made this one line of code change to deal with this; other than that, I didn't make any other modifications to the code.
As an alternative, I'm considering attaching multiple hotspots as sub-objects of the game, and then getting the labels of these hotspots and using them. However, this is too complicated, so I'd like to be able to use existing methods as much as possible.
Ah, missed this.
You need to replace "-1" with "0". Untranslated lines should have an ID of -1.
Thank you as always for your support and response.
Sadly, despite incorporating your suggestions, the issue has not been resolved. Could you please take another look at my code?
using AC;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharManager : MonoBehaviour, ITranslatable
{
}
The behaviour will be different, even if it doesn't work. What's the exact behaviour you're getting now, and what do the Speech Manager - and Char Manager component - look like after gathering speech text?
One thing to bear in mind is that you'll need to ensure any untranslated labels have a line ID of -1. This should be automatic, but Unity may not set the correct default value here when increasing the Label Datas array in the Inspector.
https://imgur.com/a/7IqoXg2
Let me explain what happened to the program after the modification.
First of all, the IDs in the CSV file now start at 0 instead of -1.
Also, I was getting the same error for hover, item, except for speech (but I'm not sure if this was the case originally, or if it changed after the fix - I think it was the latter).
And when I created the label data, I explicitly set the default id to -1. So I think the default id for the untranslated data is probably -1.
When I run the gather text function, the sentences are gathered fine. I even got the input right, it's just the translation that doesn't run.
Let me explain the function of charmanager.
If you click on the specified area, it directly gets the label data from charmanager and displays it in the specified area.
Thank you so much for your responses each time, your attention is very helpful to me!
Is that shot of the CharManager Inspector taken after the gather-text process?
This process should update the ID values to the corresponding ones listed in the Speech Manager (via the SetTranslationID function). Is that what the "1" listed in your Console is referring to?
I wonder if it's a case of the update not being saved. AC should mark the component as "dirty" automatically - i.e. flag it as having had changes necessary to save - but you could try doing so manually by adding this to the function as well:
After collecting the text, the ID remains unchanged and is labeled -1.
This was true even though I included EditorUtility.SetDirty(this); in the SetTranslationID function.
So, after assigning a translation to the text, I substituted the ID of that labeldata with the ID value registered in speech manager. I thought this would work, but alas, nothing changed.
I can't recreate the issue on my end - the component is updated as intended.
To be clear: the component is present on a GameObject in a dedicated scene? What are your AC/Unity versions?
Have you tried adding in a Debug.Log function to SetTranslationID, to confirm that it is being run (and ID is being set)?
If it shows, share the message in full (stacktrace included) for a typical line.