Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Country/Region location detection for High score postings

Discussion in 'iOS and tvOS' started by rmlloyd, Sep 24, 2010.

  1. rmlloyd

    rmlloyd

    Joined:
    Jul 22, 2008
    Posts:
    82
    Hi,

    I am creating a online highscore system with mysql/php and have gotten quite far with it.

    Is there a way I can detect the users Country location from the iPad? I would like to register this when they create a profile name as it would add some add some colour to the high score table (which would otherwise simply be profile + score).

    thanks for your help.
     
  2. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,455
    Good idea! Now I'm thinking of adding such a feature in my iPhone game's online highscores too.

    You can use iPhoneSettings.StartLocationService (specific to Unity iPhone 1.7, don't know if the name's been changed since 3.0) to use the GPS and get the longtitude and latitude, and from there you can find the country based on a reverse geo-coding lookup, like this one: http://tinygeocoder.com/create-api.php?g=33.790348,-117.226085

    Alternatively, you can get the device's IP address and get the country by using a whois lookup, like this one: http://wq.apnic.net/apnic-bin/whois.pl/apnic-bin/whois.pl/ This requires the device to be connected to the Internet, but since your highscore system is online in the first place, that's not much of a problem.

    I'd go for the GPS method though, since country info on whois databases can get outdated (though not likely).

    You can spice things up by using a flag icon from the set found here (public domain): http://www.phoca.cz/documents/35-gimp/127-flag-icons
     
    Last edited: Oct 26, 2010
  3. Agustin-Petrini

    Agustin-Petrini

    Joined:
    Nov 16, 2012
    Posts:
    25
    Hey.
    I just spent the last hour or so writing this script, thought in sharing in case it saves someone some time.
    I just tested for a bit and it works, but I don't guarantee it will work in all cases.

    Cheers.

    Code (csharp):
    1.     public string playerPrefsKey = "Country";
    2.     public void getGeographicalCoordinates()
    3.     {
    4.         if(Input.location.isEnabledByUser)
    5.             StartCoroutine(getGeographicalCoordinates());
    6.     }
    7.     private IEnumerator getGeographicalCoordinatesCoroutine()
    8.     {
    9.         Input.location.Start();
    10.         int maximumWait = 20;
    11.         while(Input.location.status == LocationServiceStatus.Initializing  maximumWait > 0)
    12.         {
    13.             yield return new WaitForSeconds(1);
    14.             maximumWait--;
    15.         }
    16.         if(maximumWait < 1 || Input.location.status == LocationServiceStatus.Failed)
    17.         {
    18.             Input.location.Stop();
    19.             yield break;
    20.         }
    21.         float latitude = Input.location.lastData.latitude;
    22.         float longitude = Input.location.lastData.longitude;
    23. //      Asakusa.
    24. //      float latitude = 35.71477f;
    25. //      float longitude = 139.79256f;
    26.         Input.location.Stop();
    27.         WWW www = new WWW("https://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latitude + "," + longitude + "&sensor=true");
    28.         yield return www;
    29.         if(www.error != null) yield break;
    30.         XmlDocument reverseGeocodeResult = new XmlDocument();
    31.         reverseGeocodeResult.LoadXml(www.text);
    32.         if(reverseGeocodeResult.GetElementsByTagName("status").Item(0).ChildNodes.Item(0).Value != "OK") yield break;
    33.         string countryCode = null;
    34.         bool countryFound = false;
    35.         foreach(XmlNode eachAdressComponent in reverseGeocodeResult.GetElementsByTagName("result").Item(0).ChildNodes)
    36.         {
    37.             if(eachAdressComponent.Name == "address_component")
    38.             {
    39.                 foreach(XmlNode eachAddressAttribute in eachAdressComponent.ChildNodes)
    40.                 {
    41.                     if(eachAddressAttribute.Name == "short_name") countryCode = eachAddressAttribute.FirstChild.Value;
    42.                     if(eachAddressAttribute.Name == "type"  eachAddressAttribute.FirstChild.Value == "country")
    43.                         countryFound = true;
    44.                 }
    45.                 if(countryFound) break;
    46.             }
    47.         }
    48.         if(countryFound  countryCode != null)
    49.             PlayerPrefs.SetString(playerPrefsKey,countryCode);
    50.     }
     
    Last edited: Nov 19, 2012
    jvo3dc and BlackPanda like this.
  4. BlackPanda

    BlackPanda

    Joined:
    Jan 24, 2014
    Posts:
    76
    Thanks a lot pal. :) But there's a slight mistake in that code. Line 16 should be changed to this:
    Code (CSharp):
    1. if(maximumWait < 1 && Input.location.status == LocationServiceStatus.Failed)
     
  5. i42-Xblade

    i42-Xblade

    Joined:
    Jan 12, 2016
    Posts:
    522
    Thanks mate,

    But you are missing a lot of
    Code (CSharp):
    1. &&
    's, randomly. Maybe Unity forums prevent it?

    Also

    Code (CSharp):
    1. StartCoroutine(getGeographicalCoordinates());
    is displaying error: Can't convert void into IEnumerator
     
  6. Yulian_Titov

    Yulian_Titov

    Joined:
    Apr 18, 2016
    Posts:
    1
    Hi,

    I made a solution which will give ability to get approximate Country Code. Maybe it will be helpful for you:

    Code (CSharp):
    1.  
    2.         private static readonly Dictionary<SystemLanguage,string> COUTRY_CODES = new Dictionary<SystemLanguage, string>()
    3.         {
    4.             { SystemLanguage.Afrikaans, "ZA" },
    5.             { SystemLanguage.Arabic    , "SA" },
    6.             { SystemLanguage.Basque    , "US" },
    7.             { SystemLanguage.Belarusian    , "BY" },
    8.             { SystemLanguage.Bulgarian    , "BJ" },
    9.             { SystemLanguage.Catalan    , "ES" },
    10.             { SystemLanguage.Chinese    , "CN" },
    11.             { SystemLanguage.Czech    , "HK" },
    12.             { SystemLanguage.Danish    , "DK" },
    13.             { SystemLanguage.Dutch    , "BE" },
    14.             { SystemLanguage.English    , "US" },
    15.             { SystemLanguage.Estonian    , "EE" },
    16.             { SystemLanguage.Faroese    , "FU" },
    17.             { SystemLanguage.Finnish    , "FI" },
    18.             { SystemLanguage.French    , "FR" },
    19.             { SystemLanguage.German    , "DE" },
    20.             { SystemLanguage.Greek    , "JR" },
    21.             { SystemLanguage.Hebrew    , "IL" },
    22.             { SystemLanguage.Icelandic    , "IS" },
    23.             { SystemLanguage.Indonesian    , "ID" },
    24.             { SystemLanguage.Italian    , "IT" },
    25.             { SystemLanguage.Japanese    , "JP" },
    26.             { SystemLanguage.Korean    , "KR" },
    27.             { SystemLanguage.Latvian    , "LV" },
    28.             { SystemLanguage.Lithuanian    , "LT" },
    29.             { SystemLanguage.Norwegian    , "NO" },
    30.             { SystemLanguage.Polish    , "PL" },
    31.             { SystemLanguage.Portuguese    , "PT" },
    32.             { SystemLanguage.Romanian    , "RO" },
    33.             { SystemLanguage.Russian    , "RU" },
    34.             { SystemLanguage.SerboCroatian    , "SP" },
    35.             { SystemLanguage.Slovak    , "SK" },
    36.             { SystemLanguage.Slovenian    , "SI" },
    37.             { SystemLanguage.Spanish    , "ES" },
    38.             { SystemLanguage.Swedish    , "SE" },
    39.             { SystemLanguage.Thai    , "TH" },
    40.             { SystemLanguage.Turkish    , "TR" },
    41.             { SystemLanguage.Ukrainian    , "UA" },
    42.             { SystemLanguage.Vietnamese    , "VN" },
    43.             { SystemLanguage.ChineseSimplified    , "CN" },
    44.             { SystemLanguage.ChineseTraditional    , "CN" },
    45.             { SystemLanguage.Unknown    , "US" },
    46.             { SystemLanguage.Hungarian    , "HU" },
    47.         };
    48.  
    49.         /// <summary>
    50.         /// Returns approximate country code of the language.
    51.         /// </summary>
    52.         /// <returns>Approximated country code.</returns>
    53.         /// <param name="language">Language which should be converted to country code.</param>
    54.         public static string ToCountryCode(this SystemLanguage language) {
    55.             string result;
    56.             if (COUTRY_CODES.TryGetValue (language, out result)) {
    57.                 return result;
    58.             } else {
    59.                 return COUTRY_CODES[SystemLanguage.Unknown];
    60.             }
    61.         }
    62.  
    Usage is simple:

    Code (CSharp):
    1. var countryCode = Application.systemLanguage.ToCountryCode();
    With best regards,
    Yulian
     
    Krucho likes this.
  7. Vorlex

    Vorlex

    Joined:
    Jan 10, 2013
    Posts:
    2
    There is a couple of incorrect country codes (corresponding to ISO 3166-1) in your dictionary. For example, for
    Greek and SerboCroatian language.

    Here is dictionary with correct country codes:
    Code (CSharp):
    1.         private static readonly Dictionary<SystemLanguage, string> CountryCodes = new Dictionary<SystemLanguage, string>
    2.         {
    3.             { SystemLanguage.Afrikaans, "af-ZA"},
    4.             { SystemLanguage.Arabic, "ar-SA"},
    5.             { SystemLanguage.Basque, "eu-ES"},
    6.             { SystemLanguage.Belarusian, "be-BY"},
    7.             { SystemLanguage.Bulgarian, "bg-BG"},
    8.             { SystemLanguage.Catalan, "ca-ES"},
    9.             { SystemLanguage.Chinese, "zh-CN"},
    10.             { SystemLanguage.Czech, "cs-CZ"},
    11.             { SystemLanguage.Danish, "da-DK"},
    12.             { SystemLanguage.Dutch, "nl-NL"},
    13.             { SystemLanguage.English, "en-US"},
    14.             { SystemLanguage.Estonian, "et-EE"},
    15.             { SystemLanguage.Faroese, "fo-FO"},
    16.             { SystemLanguage.Finnish, "fi-FI"},
    17.             { SystemLanguage.French, "fr-FR"},
    18.             { SystemLanguage.German, "de-DE"},
    19.             { SystemLanguage.Greek, "el-GR"},
    20.             { SystemLanguage.Hebrew, "he-IL"},
    21.             { SystemLanguage.Hungarian, "hu-HU"},
    22.             { SystemLanguage.Icelandic, "is-IS"},
    23.             { SystemLanguage.Indonesian, "id-ID"},
    24.             { SystemLanguage.Italian, "it-IT"},
    25.             { SystemLanguage.Japanese, "ja-JP"},
    26.             { SystemLanguage.Korean, "ko-KR"},
    27.             { SystemLanguage.Latvian, "lv-LV"},
    28.             { SystemLanguage.Lithuanian, "lt-LT"},
    29.             { SystemLanguage.Norwegian, "no-NO"},
    30.             { SystemLanguage.Polish, "pl-PL"},
    31.             { SystemLanguage.Portuguese, "pt-PT"},
    32.             { SystemLanguage.Romanian, "ro-RO"},
    33.             { SystemLanguage.Russian, "ru-RU"},
    34.             { SystemLanguage.SerboCroatian, "sr-RS"}, //HR for Croatia
    35.             { SystemLanguage.Slovak, "sk-SK"},
    36.             { SystemLanguage.Slovenian, "sl-SI"},
    37.             { SystemLanguage.Spanish, "es-ES"},
    38.             { SystemLanguage.Swedish, "sv-SE"},
    39.             { SystemLanguage.Thai, "th-TH"},
    40.             { SystemLanguage.Turkish, "tr-TR"},
    41.             { SystemLanguage.Ukrainian, "uk-UA"},
    42.             { SystemLanguage.Vietnamese, "vi-VN"},
    43.             { SystemLanguage.Unknown, "zz-US" }
    44.         };

    P.S. I have added language code (according to ISO 639) as prefix for each member my needs, you can remove it if you don't need it.
     
    Krucho likes this.
  8. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    2,858
    Is this the necromancer's Wednesday guild meeting? I'm a member, but my card is in the other robe.

    I think letting people self-identify their country of origin is best (use GeoIP to suggest a flag though). Don't let them change this too often, and ensure they're removed from/moved to the right table when they change it. Geolocation is often inaccurate for ISPs with international branches, like a couple of the ones we have in Norway.

    One of the popular cable companies had IP addresses identifying as Dutch at times because of the parent company being Dutch. My current ISP at least identifies the country correctly (for now; Swedish owners took over), but the city is a few hundred kilometres off for many of the addresses I get (it changes monthly).
     
  9. kishor-int

    kishor-int

    Joined:
    May 12, 2016
    Posts:
    1


    I could not get the postal_code form google response. except that, country, premise and other works !.