简体   繁体   中英

Get user's ISO 3166-1 alpha-2 country code

I'd like to know a reliable way to get the user's ISO 3166-1 alpha-2 (2-letter code, ex : US, CA) with c# in unity3d ?

I've tried RegionInfo.TwoLetterISORegionName but it returns an empty string.

Are they not implemented ?

How do I do this ?

EDIT : The main error I'm getting here is that the TwoLetterISORegionName is empty when I try and get it. The CultureInfo and RegionInfo are always returning United States as the culture unless I use this workaround :

[System.Runtime.InteropServices.DllImport("KERNEL32.DLL")]
private static extern int GetSystemDefaultLCID();

RegionInfo regionInfo = new RegionInfo(GetSystemDefaultLCID());
CultureInfo cultureInfo = new CultureInfo(GetSystemDefaultLCID());

However, the TwoLetterISORegionName is empty and the ThreeLetterWindowsRegionName returns something like "Canada", which is no good for me.

Hope that clarifies things.

UPDATE :

Here's the Debug information I get using the code above :

    Debug.Log("----- REGION INFO -----"); // Empty
    Debug.Log("CurrencyEnglishName : " + regionInfo.CurrencyEnglishName); // Empty
    Debug.Log("CurrencyNativeName : " + regionInfo.CurrencyNativeName); // Not implemented exception
    Debug.Log("CurrencySymbol : " + regionInfo.CurrencySymbol); // CAD
    Debug.Log("DisplayName : " + regionInfo.DisplayName); // Empty
    Debug.Log("EnglishName : " + regionInfo.EnglishName); // Empty
    Debug.Log("GeoId : " + regionInfo.GeoId); // 959515600
    Debug.Log("IsMetric : " + regionInfo.IsMetric); // True
    Debug.Log("ISOCurrencySymbol : " + regionInfo.ISOCurrencySymbol); // Canadian Dollar
    Debug.Log("Name : " + regionInfo.Name); // Empty
    Debug.Log("NativeName : " + regionInfo.NativeName); // Empty
    Debug.Log("ThreeLetterISORegionName : " + regionInfo.ThreeLetterISORegionName); // Empty
    Debug.Log("ThreeLetterWindowsRegionName : " + regionInfo.ThreeLetterWindowsRegionName); // Canada
    Debug.Log("TwoLetterISORegionName : " + regionInfo.TwoLetterISORegionName); // Empty

Obviously those are wrong values (well it's right, I'm in Canada and all, but the 3 letter code isn't "Canada", and the geoid can't be that big a number last I checked), or I'm missing something !

UPDATE2 : Upon further testing outside and inside of the Unity Editor, I've come to realize that the GeoID is always different... almost like a random number generator ! That feels wrong... Anyone has any ideas ?

Finally ended up finding a solution... and I'm not liking it, but hell it works. Opened up Visual Express 2008 (important that it is 2008, because you can't change target .NET platform on later versions, I believe) and created a .dll using the exact same class (RegionInfo) that I would have used in Unity C#.

So in C++/CLR : Create a .dll with a function that takes a char* as a parameter, assign the 2 characters from the System::String you get from the TwoLetterISORegionName and thats it. Copy the .dll in the plugins folder in Unity.

In C#/Unity : Link the .dll using DllImport and your method name (the method will not take a char* here but a IntPtr). Allocate the bytes to the IntPtr here, then call the C++ function, then Read the bytes, (cast them as chars for every index), and finally don't forget to release the memory. Allocate, Read and Release were used with the Marshal class.

This wouldn't work very well with a ton of characters but since I have only 2 it's not too bad. I realize this is a sketchy solution at best and demands a lot of work but since the RegionInfo class doesn't work well in Unity this is what I came up with. Hope I might help someone out !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM