Hey all,
Is there an easy way ( plugin ? ) that will switch languages (based on the device’s preference) in my app if i have the translations?
thanks, Chris
Hey all,
Is there an easy way ( plugin ? ) that will switch languages (based on the device’s preference) in my app if i have the translations?
thanks, Chris
i did this in xCode once. I had one file holding all the strings (file called “Localizable.strings”). This holds a lot of pairs like “ingameStr_4” = “, c’est tu tour!”; In XCode, you can make this file localizable. Actually a copy is created and placed in a folder for the respective language. German folder would be “de.lproj”. Then you need a “PlugIn” a C++ file that receives calls from unity to do something and return something. in this case those strings. For this you need to read about plugins in the Unity docs.
i can show you my specific plug in. It will only enlighten you if you can write objective C and read the docs about PlugIns.
The PlugIn file name is “getInternationLang”
Header file “getInternationLang.h” is
#import <Foundation/Foundation.h>
@interface getInternationLang : NSObject {
}
- (NSString *)getString:(NSString*)thekey comment:(NSString*)thecomment;
- (NSString *)getLocale;
@end
“getInternationLang.mm” is
#import "getInternationLang.h"
#import "ReviewRequest.h"
@implementation getInternationLang
- (NSString *)getString:(NSString*) thekey comment: (NSString*)thecomment
{
//NSLog(@"getInternationLang thekey %@ %@", thekey, thecomment);
NSString *localized = NSLocalizedStringFromTable (thekey, @"Localizable", thecomment);
return localized;
}
- (NSString *)getLocale
{
/*
NSLocale *locale = [NSLocale currentLocale];
NSString *shortLocale = [locale localeIdentifier];
NSLog(@"getInternationLang getLocale %@", shortLocale);
*/
NSArray* languages = [NSLocale preferredLanguages];
NSString* preferredLang = [languages objectAtIndex:0];
//NSLog(@"preferredLang %@", preferredLang);
return preferredLang;
}
@end
static getInternationLang* delegateObject = nil;
// Converts C style string to NSString
NSString* CreateNSString (const char* string)
{
if (string)
return [NSString stringWithUTF8String: string];
else
return [NSString stringWithUTF8String: ""];
}
// Helper method to create C string copy
char* MakeStringCopy (const char* string)
{
if (string == NULL)
return NULL;
char* res = (char*)malloc(strlen(string) + 1);
strcpy(res, string);
return res;
}
// When native code plugin is implemented in .mm / .cpp file, then functions
// should be surrounded with extern "C" block to conform C function naming rules
extern "C" {
const char* _GetString (const char* key, const char* thecomment)
{
if (delegateObject == nil)
delegateObject = [[getInternationLang alloc] init];
// By default mono string marshaler creates .Net string for returned UTF-8 C string
// and calls free for returned value, thus returned strings should be allocated on heap
//[serviceBrowser searchForServicesOfType: CreateNSString(key) inDomain: CreateNSString(comment)];
return MakeStringCopy([[delegateObject getString: CreateNSString(key) comment: CreateNSString(thecomment)] UTF8String]);
}
const char* _GetLocale ()
{
if (delegateObject == nil)
delegateObject = [[getInternationLang alloc] init];
// By default mono string marshaler creates .Net string for returned UTF-8 C string
// and calls free for returned value, thus returned strings should be allocated on heap
//[serviceBrowser searchForServicesOfType: CreateNSString(key) inDomain: CreateNSString(comment)];
return MakeStringCopy([[delegateObject getLocale] UTF8String]);
}
}
and the plugin File in Unity needs to be placed in unity and is called “GetLocalStrings.cs”
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class GetLocalStrings {
/* Interface to native implementation */
[DllImport ("__Internal")]
private static extern string _GetString (string thekey, string thecomment);
[DllImport ("__Internal")]
private static extern string _GetLocale();
/* Public interface for use inside C# / JS code */
// Returns current lookup status
public static string GetLocalizedString(string key, string Comment)
{
// Call plugin only when running on real device
if (Application.platform != RuntimePlatform.OSXEditor)
{
return _GetString(key, Comment);
}
// Return mockup values for code running inside Editor
else
{
return "Done";
}
}
public static string GetLocale()
{
// Call plugin only when running on real device
if (Application.platform != RuntimePlatform.OSXEditor)
{
return _GetLocale();
}
// Return mockup values for code running inside Editor
else
{
return "Done";
}
}
}
Now you need to call all this somehow, right?
so inside your whatever script, where you want to get all those scripts you do something like this (in this case JS Syntax) BEWARNED: This script is doing specific stuff, so it will not work or just crash an your side. Pick Out a very simple call and see if something gets returned. This also Only works on the device!!!
So look for a line like GetLocalStrings.GetLocalizedString(“player_2”, “playernames”); thats the most basic. It will fetch a key value thing from the Localizable in XCode. In my Case it writes it to a standardStrings class. This holds also all the strings in english (or another language), so you can see something in the editor.
function Awake() {
// Text Localization
standardStrings.init();
// Versuche localisierte Strings über C# Plugin von Objective C zu holen
supportedLang_arr = new Array();
supportedLang_arr.Push("en");
supportedLang_arr.Push("de");
supportedLang_arr.Push("es");
supportedLang_arr.Push("it");
supportedLang_arr.Push("fr");
lang = GetLocalStrings.GetLocale();
if (lang == "Done") {
//Debug.Log("We are in Editor, Connot get Objective C Country Settings");
} else {
//Debug.Log("Result of GetLocalStrings.GetLocale()= " + lang);
// returns something like "de_DE"
}
var checklang : boolean = false;
for (var i : int = 0 ; i < supportedLang_arr.length; i++) {
if (supportedLang_arr[i] as String == lang) {
checklang = true;
break;
}
}
if (checklang == false) {
lang = supportedLang_arr[0];
}
var checkNameForEditor : String = GetLocalStrings.GetLocalizedString("player_1", "playernames");
if (checkNameForEditor == "Done") {
//Debug.Log("We are in Unity Editor. Not Possible to recieve Strings");
} else {
//Debug.Log("Result from GetLocalStrings.GetLocalizedString('player_1', 'playernames')= " + checkNameForEditor);
// get localized Texts
standardStrings.names_arr[0] = checkNameForEditor;
standardStrings.names_arr[1] = GetLocalStrings.GetLocalizedString("player_2", "playernames");
standardStrings.names_arr[2] = GetLocalStrings.GetLocalizedString("player_3", "playernames");
standardStrings.names_arr[3] = GetLocalStrings.GetLocalizedString("player_4", "playernames");
standardStrings.fieldWords_arr[0] = GetLocalStrings.GetLocalizedString("field_0", "fieldplural");
standardStrings.fieldWords_arr[1] = GetLocalStrings.GetLocalizedString("field_1", "fieldplural");
var guiStrLength : int = standardStrings.guiStr_arr.length;
for(i = 0; i < guiStrLength; i++) {
standardStrings.guiStr_arr[i] = GetLocalStrings.GetLocalizedString("guistr_" + i, "guistrings");
}
var ingameStrLength : int = standardStrings.ingameStr_arr.length;
for(i = 0; i < ingameStrLength; i++) {
standardStrings.ingameStr_arr[i] = GetLocalStrings.GetLocalizedString("ingameStr_" + i, "ingamestrings");
}
var settingsStrLength : int = standardStrings.settingsStr_arr.length;
for(i = 0; i < settingsStrLength; i++) {
standardStrings.settingsStr_arr[i] = GetLocalStrings.GetLocalizedString("settingStr_" + i, "settingstrings");
}
var helpStrLength : int = standardStrings.helpStr_arr.length;
for(i = 0; i < helpStrLength; i++) {
standardStrings.helpStr_arr[i] = GetLocalStrings.GetLocalizedString("helpStr_" + i, "helpstrings");
}
var quitStrLength : int = standardStrings.quitStr_arr.length;
for(i = 0; i < quitStrLength; i++) {
standardStrings.quitStr_arr[i] = GetLocalStrings.GetLocalizedString("quitStr_" + i, "quitstrings");
}
}
}
Again, this woll only help you if you can do some XCode and Objective C and read the docs/made one tutorial about plugins in IOS.
The code is also somewhat older, might not run immediatly in the latest unity version. If it does not, its because of strct typing.
But: Google for Prime31. He has all the iOs Plugins. Don´t know about localization though.