Unreal Engine 4 i lokalizacja czyli tłumaczę jak tłumaczyć

Po n-tym projekcie w Unreal Engine dopadło mnie przemyślenie, że lokalizację podpina się często na końcu (bo tłumaczenia językowe spływają nam na koniec, korekty etc.), ale w sumie – lokalizacja jest jedną z rzeczy, która – teoretycznie nie zajmuje dużo czasu, ale podobnie jak struktura danych, ustalenie struktury Game Instance / Subsystemów / GameMode / Save’ów powinno dla mojego komfortu ruszac chociaż w podstawowej wersji od razu. Dlaczego? Higiena, po prostu łatwiej tym operować mając to działające od początku niż potem szukać wszystkich elementów do tłumaczeń i przełączać je, dodatkowo łatwiej testować UI mając jakkolwiek wersje językowe (kwestia przestrzeni na elementy). Czyli po kolei:

  1. Robimy folder dla przykładu o nazwie “Strings”.
  2. W tym folderze robimy tablicę stringową (String Table) UI_Strings
  3. Za każdym razem jak mamy coś dodać w formie tekstu do HUDa czy gdziekolwiek do wyświetlania, to najpierw dodajemy to do tej tablicy i podpinamy wyświetlanie tego z tablicy.
  4. To nie ma być przekładanie Tomasza Manna “W poszukiwaniu straconego czasu” tylko dodanie startowo jednego słowa typu “Version”.
  5. W Localization Dashbord (nie bać się określenia, że to nadal eksperymentalny plugin) definiujemy target pt. Game. Można nazwać inaczej – ale sens jest prosty -> to ma być nasz build gry. Nie silnik, nie edytor.
  6. Wskazujemy w części “Gather from Packages” nasz folder z UI_Strings
  7. Uruchamiamy przyciskiem “Gather from all targets in project” zaczytanie wszystkich materiałów do tłumaczenia.
  8. Dodajemy drugi język (Add New Culture) i edytujemy teksty do tłumaczenia (edit translation for this culture). Tutaj oczywiście uprościłem, bo tłumaczenie i obsługa plików typu .po wymagało by poważniejszego potraktowania – tutaj przepis jest na prostą lokalizację UI, tak aby ustawić projekt i zacząć myśleć o tym jak drugi język wygląda i wpływa na elementy HUDa czy UI.
  9. Kompilujemy tłumaczenia (compile translations for all cultures of this target.
  10. Mamy to, możemy teraz zaczytywać listy gotowych lokalizacji (języków) i przełączać je sobie.

Oczywiście możemy po prostu też odczytać długość takiej tablicy:

Jeżeli jednak coś Wam się dzieje i przełączanie lokalizacji nie działa (tzn. lokalizacje w Unreal Engine są, ich ilość się zgadza – to warto zrobić sobie taką prostą funkcję, która sprawdzi i poda nam w logu zarejestrowane (registered) tablice typu String.

Jest to też pomocne do określenia odwołania do tablicy – w przypadku tablic będących assetami stworzonymi w edytorze będzie to ścieżka relatywna do tablicy względem projektu, w przypadku plików .csv z tablicą stringową inicjowanych (rejestrowanych) przez kod makro

LOCTABLE_FROMFILE_GAME

w C++ będzie to sama nazwa. Procedura użycia tego makro jest opisana w dokumentacji silnika niestety dość ogólnikowo, ale można sobie z tym poradzić przy posiadaniu podstawowej wiedzy czyli m.in. tych informacji podanych powyżej. Ważne, aby pamiętać o wskazaniu narzędziu do lokalizacji właściwych zasobów do zaczytania oraz o załączeniu tych zasobów przy pakowaniu projektu do builda, co nie jest oczywiste w przypadku plików nie będących assetami.

Osobiście skłaniam się bardziej ku rozwiązaniu z plikami .csv, ich edycja daje oczywiście natychmiastowy rezultat w danych, plus… można to zrobić poza Unreal Engine.

Trzeba tylko pamięcać o jednym – w edytorze nie zobaczymy przełączeń lokalizacji za pomocą projektu poza Standalone Play. Ja dla higieny robie po prostu dev builda – oczywiście łatwiej puścić play w edytorze i wyfiltrowywać sobie od razu odpowiednie statusy, których używamy do monitoringu kodu/logiki, ale – rzecz równie praktyczna – edytor to “projekt” odpalony w silniku. Edytor odpala nasz projekt – czyli mamy już dwa “projekty” odpalone w jednym silniku. Przypadków wywalania się Unreal Engine 4 z projektem odpalonym w edytorze vs doskonale działający build mogę przewoływać w dużej liczbie.

I jeżeli myślicie, że to wszystko i to pięknie działa to – bo program odpalony jako Standalone działa i pięknie przełącza lokalizację to zmartwię Was: jak zrobicie builda to okazuje się, że jeszcze nie wszystko, bo nie działa – na szczęście to znany temat – więc mogę spokojnie zakończyć to jak Steve Jobs – ONE MORE THING:

11. Potrzebujemy jeszcze przestawić projekt pod kontem załączania lokalizacji (packaging), czyli Project Settings -> Project Packaging -> Localizations to Package, klikam dla łatwości tematu “show localized” i zaznaczam przetłumaczone języki i warianty – w moim przypadku startowo English i Polish.

I to tyle, mam nadzieję, że wytłumaczyłem “jak tłumaczyć”.

A jeżeli nie działa?

Szukamy odpowiedzi w logu. Jeżeli będzie to coś takiego jak:

UATHelper: Packaging (Windows): LogPaths: Warning: No paths for game localization data were specifed in the game configuration. 
PackagingResults: Warning: No paths for game localization data were specifed in the game configuration.

to w podkatalogu Config w pliku DefaultGame.ini szukamy poniższej linijki i zmieniamy minus na początku linijki z LocalizationPaths na plus, żeby wyglądało jak poniżej.

[Internationalization]
+LocalizationPaths=%GAMEDIR%Content/Localization/Game