Моддинг в Bannerlord: TextObject
Оригинал статьи - https://docs.bannerlordmodding.com/_csharp-api/localization/textobject.html
Общая информация
Класс TextObject необходим для локализации внутриигровых текстов. Было бы неплохо использовать этот класс для любой информации, которая может когда-либо быть показана игроку. TextObject требует строку, в качестве основного аргумента. Её можно создать с использованием аргументов типа int или float, и в этом случае они преобразуются в строку в конструкторе.
Строковые идентификаторы (ID)
Чтобы стать полностью локализуемыми, строки, используемые в TextObjects, должны начинаться с stringID:
private const string exampleString = "{=stringID}Some text";
public static readonly TextObject exampleTextObject = new TextObject (exampleString);
String ID - это строковый ключ произвольной длины и содержания без пробелов. Не рекомендуется использовать длинные строковые идентификаторы, поскольку это сказывается на производительности. Кроме того, идентификаторы строк являются глобальными, поэтому даже если две разные строки с одинаковым идентификатором строки будут созданы и использованы в разных игровых модулях, они все равно будут конфликтовать (и тогда могут произойти некоторые довольно неприятные вещи). Следовательно, не рекомендуется регулярно использовать семантически значимые ключи в качестве строковых идентификаторов. Вместо этого используйте X-значные буквенно - цифровые коды строк , которые, которые выглядят следующим образом: {=zmR6sT03}. На данный момент TaleWords и большинство разработчиков игр в большинстве случаев используют 8-значные буквенно-цифровые строковые коды для генерации строковых идентификаторов. Вы можете использовать этот сервис для генерации случайных ключей: https://www.random.org/strings/. Конечно, случайные совпадения все еще возможны, но маловероятны.
Более подробную информацию об использовании строковых идентификаторов в XML-файлах игры можно найти в статье Локализация.
Текстовые переменные
Строки, используемые в TextObjects, могут содержать переменные, которые сами являются TextObjects. Переменные хранятся в Attributes:
public Dictionary<string, TextObject> Attributes
Определение текстовых переменных Есть два способа определить текстовую переменную для TextObject. Вы можете сделать это в конструкторе или с помощью метода SetTextVariable:
private const string SOME_STRING = "{=r6NczU68} Some text {TEXT_VARIABLE} more text {OTHER_TEXT_VARIABLE}.";
public static TextObject GetSomeStringAsTextObject()
{
TextObject result = new TextObject(SOME_STRING, new Dictionary<string, TextObject>() { ["TEXT_VARIABLE"] = new TextObject("Variable value") });
string s = "Other variable value";
result.SetTextVariable("OTHER_TEXT_VARIABLE", s);
return result;
}
Сложные текстовые переменные и регистры
Поскольку все текстовые переменные сами являются объектами TextObject, они могут быть довольно сложными. Обратите внимание, что любые переменные, установленные для внешнего TextObject, могут использоваться как свойства во внешнем TextObject. Также стоит отметить, что у TextObjects есть базовый встроенный условный процессор. Рассмотрим следующий пример:
private const string MAIN_STRING =
"{=stringIDMain}I spent {NESTED_TEXT_OBJECT} this example! " +
"By the way, using of number {VARIABLE_TAG} requires {VARIABLE_TAG.NESTED_PROPERTY} after it! " +
"{BIT_FLAG}Conditional text example for when value of bitFlag = 1{?}Another conditional text example for when value of bitFlag = 0{\\?}.";
private const string NESTED_STRING = "{=stringIDNested}{MINUTES} minutes to come up with and write";
private const string NESTED_PROPERTY_SINGULAR = "{=ie0XDdqR}singular noun";
private const string NESTED_PROPERTY_PLURAL = "{=oRPbCfYq}plural noun";
public static TextObject GetMainTextObject(int variable, bool flag)
{
TextObject mainTextObject = new TextObject(MAIN_STRING);
TextObject nestedTextObject = new TextObject(NESTED_STRING,
new Dictionary<string, TextObject>() { ["MINUTES"] = new TextObject(variable) });
mainTextObject.SetTextVariable("NESTED_TEXT_OBJECT", nestedTextObject);
TextObject variableTextObject = new TextObject(variable);
variableTextObject.SetTextVariable("NESTED_PROPERTY", variable == 1 ? NESTED_PROPERTY_SINGULAR : NESTED_PROPERTY_PLURAL);
mainTextObject.SetTextVariable("VARIABLE_TAG", variableTextObject);
mainTextObject.SetTextVariable("BIT_FLAG", flag ? 1 : 0);
return mainTextObject;
}
Тогда использование GetMainTextObject(40, true).ToString();вернет следующую строку:
"I spent 40 minutes to come up with and write this example! By the way, using of number 40 requires plural noun after it! Conditional text example for when value of bitFlag = 1."
Примечание о вложенных свойствах
Использование вложенных свойств для сложных объектов может быть очень полезно любому, кто переводит ваш мод. Рассмотрим следующий пример из кода TaleWorlds:
TextObject textObject = new TextObject("{=jF4Nl8Au}{NPC_LIEGE.NAME}, {LIEGE_RELATIONSHIP}? Long may {?NPC_LIEGE.GENDER}she{?}he{\\?} live.");
StringHelpers.SetCharacterProperties("NPC_LIEGE", Hero.OneToOneConversationHero.Clan.Leader.CharacterObject, null, textObject, false);
Метод StringHelpers.SetCharacterProperties используется для установки нескольких атрибутов, связанных с символами, которые используются в строке TextObject. В этом примере используются Имя и Пол персонажа. Добавление такой информации к любой строке, в которой упоминается символ, было бы разумным решением, потому что даже если вам не нужен пол в этой строке на английском языке, он может пригодится переводчикам на другие языки.Однако будьте осторожны, использование нескольких уровней вложенности для свойств не поддерживается, поэтому использование чего-то вроде {NPC.CLAN.NAME}невозможно - игровой текстовый процессор вернет пустую строку, если вы используете несколько точек с одним тегом переменной.
Иногда вам нужно использовать одну и ту же информацию в нескольких TextObject. В этом случае вы можете определить глобальную текстовую переменную, которая будет использоваться текстовым процессором для любого TextObject при вызове метода .ToString().Для этого вам нужно будет использовать
MBTextManager.SetTextVariable(StringTag, TextVariable);
MBTextManager - это общедоступный статический класс. Любая установленная для него переменная будет использоваться текстовым процессором игры для любого TextObject, как если бы она была определена для самого TextObject. Если вы собираетесь использовать глобальные текстовые переменные в TextObject, вам не следует устанавливать для него какие-либо локальные текстовые переменные. Текстовый процессор игры использует переменные, хранящиеся в MBTextManager, только если экземпляр TextObject не имеет собственных атрибутов.
Язык по умолчанию
Язык игры по умолчанию - английский, поэтому любая локализуемая строка, которую вы используете во время разработки, должна быть определена на английском языке. Таким образом, английский язык никогда не будет читаться из файлов игры, но будет встроен в вашу сборку. См. дополнительную информацию о хранении ваших XML-файлов с игровыми строками в разделе Локализация.
Комментариев 0
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.