LoginSignup
7
6

More than 5 years have passed since last update.

UnityプロジェクトにおけるBundleVersion管理

Last updated at Posted at 2016-05-02

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

正規表現はあまり使わないので、こんな書き方で大丈夫か?などの意見求む!

7
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6