Pull to refresh

Comments 15

Сделайте файл с локализацией ну хотя бы тысяч на 10 строк, проверьте производительность и число аллокаций, и ужаснитесь.


Что если в строке есть символ ";" или "\n"? Что если в строку нужно подставить цифру? Что если язык меняется в процессе игры?

Да ладно, достаточно было спросить "что если я поменяю местами столбцы EN и RU".

Но вы же не меняете местами кнопки на клавиатуре...
Дурдом будет

Серьезно, я не могу столбики данных менять местами? А если у меня не будет русской локализации, а будет, допустим французская или немецкая - мне код потребуется переписывать? Это удобная локализация?

Достаточно вписать в конец Localizator.cs возвращение cuted_row[i], где i - номер столбца в файле перевода.

Я согласен, что достаточно взять нормальную реализацию локализации, чтобы она работала, только в статье ее нет, раз ее уже надо подпиливать на самых простых кейсах.

При смене языка в процессе он сменится как и надо, но при перезапуске сцены, таким образом в скрипт кнопки смены языка можно запихать и перезапуск сцены.
А вот по поводу производительности вы правы, однако фишка в удобстве и простоте реализации, речь не идет о супер-пупер играх, хотя оптимизацию можно подтянуть уменьшив кол-во обращений к файлу, например разовое чтение всего что необходимо при загрузке сцены.

У Unity недавно вышел в релиз официальный пакет для локализации

https://docs.unity3d.com/Packages/com.unity.localization@1.0/manual/index.html

Я не знаю насколько он хорош в настоящем продакшене, но выглядит удобно и продуманно.

На мой взгляд лучше попробовать его, чем отвлекаться от основной разработки на кодинг костылей, которые потом наверняка начнут любить голову.

Я пусть и джун, но решил опробовать этот новый способ локализации. И весь мой опыт хочу изложить. Во-первых, о ней мало где сказано, казалось бы, почему бы не говорить о таком хорошем инструменте на каждом шагу? Потому что он сырой, потому что документация скудная и запутанная. Потому что приложения, который билдились на андроид за 2 минуты стали билдиться по 7-10 минут после установки этого чуда. Во-вторых, там функционал полурабочий. Что я имею ввиду? Например, удобно было бы тексту на английском и русском языках менять шрифты при изменении языка, менять размер шрифта, и т.п. Они это сделали, да. Но. ТОЛЬКО КОГДА ОБЪЕКТ Active. Если он выключен, то текст и остальное внутри не изменится. С этим можно смириться изменением альфы и отлючением блокинг рейкастов(в канвасе, больше нигде не тестил). Но и эксепшены выпадают на каждом шагу, потому что плагин сырой из-за чего он работать нормально не хочет. Там есть костыль - localization String, по-моему и внутри ты указываешь таблицу, по которой происходит локализация и компоненты который изменятся при изменении языка(надеюсь понятно объяснил) ну и соответственно ячейку в этой таблице, тогда всё заработает как надо. Но оно того не стоит, потому что время билда так возросло, потому что не ловимые эксепшены вылязят, потому что ошибки в непонятных местах.
В общем. Мне не понравилось, не рекомендую.

  1. Погодите-ка, у вас для каждого объекта, которому нужна локализация, обращение к диску и чтение файла (в худшем случае, до самого конца), пока не совпадёт id? Как минимум, лучше считать один раз и положить в хешмепу.
  2. GetComponent нужно один раз в Эвейке брать, а потом к локальной переменной обращаться.
  3. Текст с подстановкой не поддерживается.
  4. Возьмите I2 Localization и не мучайтесь.

Читать файл не лучше ли сразу? Или при первом использование только открывать.

Не проще ли сразу при запуска сохранять перевод в двух словарях(Английский и русский естественно), а не каждый раз перечитывать файл?

И да у тебя в коде, после for двоеточие....

        Dictionary<string, string> locRus;
        Dictionary<string, string> locEng;
        public string id;
        void Awake()
        {  // если язык выбран...
            LoadLocal();
            if (PlayerPrefs.HasKey("GameLanguage"))
            {
                string GameLanguage = PlayerPrefs.GetString("GameLanguage");  //  RU/EN
                change_text(localized_text(id, GameLanguage));
            }
            else
            {  // если язык не выбран то английский по умолчанию
                change_text(localized_text(id, "EN"));
            }
        }

        private void change_text(string new_text)
        {
            // вставляем текст в текстовое поле объекта на котором висит скрипт
            GetComponent<Text>().text = new_text;
        }
        private void LoadLocal()
        {
            // вытаскиваем из таблицы значение
            // читаем из Resources/Localization/Localization.csv
      			TextAsset mytxtData=(TextAsset)Resources.Load("localization/localization");
            string loc_txt = mytxtData.text;
            string[] rows = loc_txt.Split('\n');
            locEng = new Dictionary<string, string>();
            locRus = new Dictionary<string, string>();
            for (int i = 1; i < rows.Length; i++)
            {
                string[] cuted_row = Regex.Split(rows[i], ";");
                //загружаем английский перевод
                locEng.Add(cuted_row[0], cuted_row[1]);
                //русский

                if(cuted_row.Length>=3)
                    locRus.Add(cuted_row[0], cuted_row[2]);
            }
        }
        private string localized_text(string id, string lang)
        {  
            Dictionary<string, string> realLoc;
            if (lang == "EN")
            {
                realLoc = locEng;
            }
            else if (lang == "RU")
            {
                realLoc = locRus;
            }
            else return "ERROR load local";
            if (realLoc.ContainsKey(id))
                return realLoc[id];
            else if (locEng.ContainsKey(id))
                return locEng[id];
            return "translation not found";  // если перевод не найден в таблице
        }

Так получше будет, я так думаю

У вас есть переменная GameLanguage в PlayerPrefs. Гораздо удобнее хранить переводы по файлам, например, так: l11n/ru.<file_ext>, l11n/en.<file_ext> и т.д. При запросе от пользователя на смену языка - у вас меняется переменная. Всё что останется - прочитать соответствующий файл и дополнить/переопределить коллекцию.

А чтобы руками не забивать это всё в файлы - заведите гугл-таблицу и напишите скрипт для экспорта в нужный вам формат. Сразу же получите бонус в виде совместного редактирования, можно отдать на перевод просто ссылку на гугл-таблицу.

Only those users with full accounts are able to leave comments. Log in, please.