在 Unity SDK 中使用本地化和语言代码
为什么这很重要
在某些场景下,语言区域代码会发挥关键作用——例如,当你需要根据应用当前的本地化设置获取对应的付费墙时。
由于语言区域代码较为复杂,且在不同平台之间可能存在差异,我们对所有支持的平台统一使用一套内部标准。正因为这些代码比较复杂,了解你实际发送给服务器的内容、以及后续的处理逻辑就显得尤为重要——这样你才能始终获取到预期的本地化结果。
Adapty 的语言代码标准
在语言代码方面,Adapty 采用了经过少量调整的 BCP 47 标准:每个代码由小写子标签组成,以连字符分隔。例如:en(英语)、pt-br(葡萄牙语(巴西))、zh(简体中文)、zh-hant(繁体中文)。
语言区域代码匹配
当 Adapty 收到客户端 SDK 传入的语言区域代码并开始查找对应的付费墙本地化版本时,流程如下:
- 传入的语言区域字符串转换为小写,所有下划线(
_)替换为连字符(-) - 查找与完整语言区域代码完全匹配的本地化版本
- 如果未找到匹配项,则取第一个连字符前的子字符串(例如
pt-br取pt),再次查找匹配的本地化版本 - 如果仍未找到匹配项,则返回默认的
en本地化版本 这样,发送'pt_BR'的 iOS 设备、发送pt-BR的 Android 设备以及发送pt-br的其他设备,都会得到相同的结果。
实现本地化:推荐方式
如果你正在考虑本地化问题,很可能项目中已经有了本地化字符串文件。在这种情况下,我们建议在每个本地化文件中加入一个键值对,其值对应 Adapty 的语言区域代码,然后在调用 SDK 时提取该键的值,示例如下:
// 1. Modify your localization files (e.g., using Unity's Localization package)
/*
en.json
*/
{
"adapty_paywalls_locale": "en"
}
/*
es.json
*/
{
"adapty_paywalls_locale": "es"
}
/*
pt-BR.json
*/
{
"adapty_paywalls_locale": "pt-br"
}
// 2. Extract and use the locale code
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using AdaptySDK;
public class PaywallManager : MonoBehaviour
{
public async void FetchPaywall()
{
// Get the current locale from Unity's Localization system
var locale = LocalizationSettings.SelectedLocale;
var localeCode = GetAdaptyLocaleCode(locale);
// Pass locale code to Adapty.GetPaywall or Adapty.GetPaywallForDefaultAudience method
Adapty.GetPaywall("placement_id", localeCode, (paywall, error) => {
if (error != null) {
// handle the error
return;
}
// Use the paywall
});
}
private string GetAdaptyLocaleCode(Locale locale)
{
// Convert Unity locale to Adapty format
var localeIdentifier = locale.Identifier.Code;
return localeIdentifier.ToLower().Replace('_', '-');
}
}
这样,您就能完全掌控应用中每位用户所获取的本地化内容。
另一种本地化实现方式
你也可以不为每个本地化版本明确定义语言区域代码,从而实现类似(但并不完全相同)的效果。这意味着需要从平台提供的其他对象中提取语言区域代码,例如:
using UnityEngine;
using System.Globalization;
using AdaptySDK;
public class PaywallManager : MonoBehaviour
{
public void FetchPaywall()
{
var localeCode = GetSystemLocaleCode();
// Pass locale code to Adapty.GetPaywall or Adapty.GetPaywallForDefaultAudience method
Adapty.GetPaywall("placement_id", localeCode, (paywall, error) => {
if (error != null) {
// handle the error
return;
}
// Use the paywall
});
}
private string GetSystemLocaleCode()
{
// Get the system's current culture
var culture = CultureInfo.CurrentCulture;
var languageCode = culture.TwoLetterISOLanguageName;
var regionCode = culture.Name.Contains('-') ? culture.Name.Split('-')[1] : null;
if (!string.IsNullOrEmpty(regionCode))
{
return $"{languageCode}-{regionCode.ToLower()}";
}
return languageCode;
}
}
请注意,我们不建议使用此方法,原因如下:
- 在 iOS 上,首选语言与当前语言区域并不相同。如果想让本地化正确生效,要么依赖 Apple 的内置逻辑(使用推荐的本地化字符串文件方案时开箱即用),要么自行重新实现该逻辑。
- 很难预测 Adapty 服务器实际会收到什么内容。例如,在 iOS 上,设备可能上报类似
ar_OM@numbers='latn'这样的语言区域标识,并将其发送到我们的服务器。而服务器收到后,返回的不会是你期望的ar-om本地化内容,而是ar,这往往会让人感到意外。 如果你仍决定采用这种方式,请确保已覆盖所有相关的使用场景。