Unityプロジェクトにおいて、BundleVersion値を管理していく必要があるが、
これがまた地味に面倒だったので、備忘録的に残しておく。
今回やりたかった事
- ヒューマンエラーを防ぐため、バージョン設定は一か所で行いたい
- 基本は[x.y.z]形式だけど、リリース後にデバッグ用にz未満のバージョンもつけたい
- アップデート通知のため、サーバにバージョン値をint型で送信したい
BundleVersionをスクリプト側で取得する
- UnityEditor上ではUnityEditor.PlayerSettingsが使用できるので楽だが、ビルド後はNativeコードを使用する必要がある模様
Unity側のコード
PluginManager.cs
using UnityEngine;
using System.Runtime.InteropServices;
public class PluginManager
{
#if !UNITY_EDITOR && UNITY_IOS
[DllImport("__Internal")]
static private extern string _GetVersionName();
#endif
static public string GetBundleVersion()
{
string bundleVersion = "0.0.0";
#if UNITY_EDITOR
bundleVersion = UnityEditor.PlayerSettings.bundleVersion;
#elif UNITY_ANDROID
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity").Call<AndroidJavaObject>("getApplicationContext");
AndroidJavaObject pManager = context.Call<AndroidJavaObject>("getPackageManager");
AndroidJavaObject pInfo = pManager.Call<AndroidJavaObject>("getPackageInfo", context.Call<string>("getPackageName"), 0);
bundleVersion = pInfo.Get<string>("versionName");
#elif UNITY_IOS
bundleVersion = _GetVersionName();
#endif
return bundleVersion;
}
}
2016/05/12追記
AndroidJavaObject pInfo = pManager.Call<AndroidJavaObject>("getPackageInfo", context.Call<string>("getPackageName"), pManager.GetStatic<int>("GET_ACTIVITIES"));
上記コードだと特定以上のAndroidOSでクラッシュする現象が起きていたので、0固定で入力するように修正。
iOS版のみNativeコードも記述する必要がある
PluginManager.mm
extern "C"
{
char* _GetVersionName();
}
char* _GetVersionName()
{
NSString *buildNo = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
char* res = (char*)malloc(strlen([buildNo UTF8String]) + 1);
strcpy(res, [buildNo UTF8String]);
return res;
}
@"CFBundleVersion" だと VersionCode を取得してしまうので、
@"CFBundleShortVersionString" を使用する。
Unityバージョンっぽく[1.0.0p1]のように定義した上でInt型に変換する
- このあたりは好みの問題なので、オマケ的な感じ。
using System.Text.RegularExpressions;
public class Temp
{
public int ClientVersionId
{
get
{
int bundleVersionId = 0;
string bundleVersion = PluginManager.GetBundleVersion();
var reg = new Regex(@"^(\d+).(\d+).(\d+)");
var match = reg.Match(bundleVersion);
if (match.Groups.Count == 4)
{
bundleVersion = string.Format("{0}{1}{2}",
match.Groups[1].ToString(),
match.Groups[2].ToString(),
match.Groups[3].ToString());
int.TryParse(bundleVersion, out bundleVersionId);
}
return bundleVersionId;
}
}
}
1.0.0と1.0.0p1は同バージョンとして扱いたいので、今回は無視するように設計。
ex)
- 1.0.0 => 100
- 2.0.7 => 207
- 1.0.0p1 => 100
正規表現はあまり使わないので、こんな書き方で大丈夫か?などの意見求む!