Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How can I get "Bundle Version" and "Bundle Version Code" through script?

Discussion in 'Android' started by Tai, Nov 24, 2010.

  1. Tai

    Tai

    Joined:
    Nov 24, 2010
    Posts:
    3
    I need to show Bundle Version and Bundle Version Code in my application,
    but looks like PlayerSettings class has no function to get these two.
    Can I get this information like PlayerSettings.iPhoneBundleIdentifier for iPhone application?
    Thanks in advance.
     
  2. eriQue

    eriQue

    Unity Technologies

    Joined:
    May 25, 2010
    Posts:
    595
    Until we add this information you will need to use need to use plugins to access Java to retrieve that info. I believe it's not available on iPhone either. Please submit a bug report ('feature request') if you need this.
     
    mvsgames_Unity likes this.
  3. Tai

    Tai

    Joined:
    Nov 24, 2010
    Posts:
    3
    Thank you.
    I will submit a feature request. :)
     
  4. litebox

    litebox

    Joined:
    Aug 29, 2011
    Posts:
    158
    So, 5 years ago you did request this feature, is it available now? :)
    Seems like we still cannot get Bundle Version and Bundle Version Code in application?
    It could be convenient, because now to show current version in game menu we have to set proper version by hands.
     
  5. phongtt

    phongtt

    Joined:
    Dec 29, 2013
    Posts:
    14
    I'm new to Unity and currently stuck with this too. Anyone has solution?
     
  6. iivo_k

    iivo_k

    Joined:
    Jan 28, 2013
    Posts:
    314
    I use a build script that saves the build info in a text file in a Resources folder, so I can read it during runtime.
     
  7. CesarNascimento

    CesarNascimento

    Joined:
    Mar 26, 2013
    Posts:
    15
    What about
    Code (CSharp):
    1. PlayerSettings.Android.bundleVersionCode
    2. PlayerSettings.bundleVersion
    Wouldn't they work for what you want?
     
    Aca, Max_Aigner, servalstar and 3 others like this.
  8. mdrotar

    mdrotar

    Joined:
    Aug 26, 2013
    Posts:
    377
    @CesarNascimento Those are only available from Editor scripts, not runtime.
     
  9. Chrisdbhr

    Chrisdbhr

    Joined:
    May 21, 2016
    Posts:
    17
    3 years and this is one of the first results on Google when searching for this.

    Anyway, using this:

    Code (CSharp):
    1. Application.version
    You can get a string with the Version of the app (set in PlayerSettings).
    This works on Android and iOS, and I believe in PC too. But I don't know yet a way to get the Bundle Package Version Code (or Bundle Version, in iOS) in runtime yet.

    Maybe this can be usefull: https://stackoverflow.com/questions/17208261/get-app-bundle-version-in-unity3d
     
    Last edited: Jan 11, 2018
  10. siavosh

    siavosh

    Joined:
    Mar 6, 2015
    Posts:
    1
    Hi, you can use this code to get Bundle version code or package name.


    AndroidJavaClass up = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

    var ca = up.GetStatic<AndroidJavaObject>("currentActivity");

    AndroidJavaObject packageManager = ca.Call<AndroidJavaObject>("getPackageManager");

    var pInfo = packageManager.Call<AndroidJavaObject>("getPackageInfo", Application.bundleIdentifier, 0);

    Debug.Log("versionCode:" + pInfo.Get<int>("versionCode"));
     
    XLoad and saud_ahmed020 like this.
  11. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Hmm, that code doesn't compile for me, even when building for Android;

    Is there still no cross-platform way to get the bundle version?
     
    Last edited: Sep 13, 2018
  12. Deleted User

    Deleted User

    Guest

    @JoeStrout Unfortunately there's not. Unity is considering an unified API call for this (response to non-public Case 1024033).
    Since Unity 5.6.0b6 the API call you receive the error for has changed:
     
    JoeStrout likes this.
  13. Sm0keh

    Sm0keh

    Joined:
    May 30, 2012
    Posts:
    17
    It's rather troubling that this feature has been requested 9 years ago and still nothing. I'm not certain of the volume of feature requests, but what is the rate of completion for feature requests anyway? Are those given any priority at all?

    I feel like this could be a very easy change to make on UT's side, can we get access to the bundle version code (Android) or build number (iOS) during runtime? The same way we now have access to the bundle identifier in Application.identifier - Can't there be an Application.buildNumber ?
     
    Jimaniki and JoeStrout like this.
  14. Fritsl

    Fritsl

    Joined:
    Mar 10, 2013
    Posts:
    211
    Bumping, have to set text files EVERY time I upload, just that extra stupid step ;/
     
    JoeStrout likes this.
  15. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Agreed. This is hard for us to do, but easy for Unity, with no unpleasant side-effects that I can see... weird that we still don't have it.
     
    Jimaniki likes this.
  16. Zandra808

    Zandra808

    Joined:
    May 9, 2017
    Posts:
    2
    Too bad we can't access this feature. I am afraid I will forget to change the version code from the editor text.
    But!!!
    Texmeshpro versionText;
    String version;

    Void Awake()
    {
    version = Application.version
    versionText. text = version;
    }
    //seems to work just fine.
     
    JoeStrout likes this.
  17. Syganek

    Syganek

    Joined:
    Sep 11, 2013
    Posts:
    85
    But it is available.

    You can set your game version string via
    Code (CSharp):
    1. PlayerSettings.bundleVersion
    And you can set your bundleVersionCode for Android via
    Code (CSharp):
    1. PlayerSettings.Android.bundleVersionCode
    or for iOS
    Code (CSharp):
    1. PlayerSettings.iOS.buildNumber
     
    Mashti, Ubrano and Sohaib_techverx like this.
  18. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    But PlayerSettings is in the UnityEditor namespace. It's not available at runtime, is it?
     
    ElasticSea and AldeRoberge like this.
  19. DeFaler

    DeFaler

    Joined:
    Jan 31, 2017
    Posts:
    10
    In general, in cases like these, you could write a pre-build script/hook that, at build time, reads the info from PlayerSettings and generates a file (JSON, scriptableObject, whatever) that you can read at runtime to populate the text field with.
     
  20. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Details on how to do that would make an excellent blog or forum post!
     
  21. naviln

    naviln

    Joined:
    Oct 18, 2016
    Posts:
    32
    Thanks! This is perfect for my build script, before I push the app bundle to Google Play.
     
  22. unity_zq9yV-QwDEEPOA

    unity_zq9yV-QwDEEPOA

    Joined:
    Dec 3, 2019
    Posts:
    2
    bundlev.text = "Bundle Version: " + UnityEditor.PlayerSettings.Android.bundleVersionCode; you're welcome bois
     
  23. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    We already covered that. UnityEditor is not available at runtime.
     
    ElasticSea likes this.
  24. MAWMatt

    MAWMatt

    Joined:
    Nov 10, 2016
    Posts:
    75
    Nearly 11 years later...nothing...?

    Also, not sure why this is confusing people, but we're looking for a way to get access to the bundle code at RUNTIME. You can post PlayerSettings all day long, that's only available via the editor. There are ways to get around this, few mentioned, but that's not really the point here...Unity should expose this to us.
     
  25. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Yep. Pretty amazing, isn't it?
     
  26. ivo-alves

    ivo-alves

    Joined:
    Sep 2, 2014
    Posts:
    4
  27. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Please read the thread before posting. Especially when it's a longish thread with a lot of useless posts in it already.

     
  28. allergicracoon

    allergicracoon

    Joined:
    Nov 9, 2014
    Posts:
    2
    Place this script in your Editor folder. It automatically writes the build number to a GameVersion.cs file in your Assets folder. You can access the various build numbers in your code through e.g. GameVersion.iOS_BuildNumber. Runs automatically on asset reload, and whenever you make a new build.

    Code (CSharp):
    1. using System.IO;
    2. using UnityEditor;
    3. using UnityEditor.Build;
    4. using UnityEditor.Build.Reporting;
    5. using UnityEditor.Callbacks;
    6. using UnityEngine;
    7.  
    8. public class VersionWriter : IPreprocessBuildWithReport
    9. {
    10.     private const string targetFile = "GameVersion.cs";
    11.  
    12.     public int callbackOrder => 0;
    13.  
    14.     public void OnPreprocessBuild(BuildReport report)
    15.     {
    16.         WriteVersion();
    17.     }
    18.  
    19.     [DidReloadScripts]
    20.     public static void WriteVersion()
    21.     {
    22.         string finalPath = Path.Combine(Application.dataPath, targetFile);
    23.  
    24.         string newText = $"public static class GameVersion\r\n" +
    25.             "{\r\n" +
    26.             FormatVar("iOS_BuildNumber", PlayerSettings.iOS.buildNumber) +
    27.             FormatVar("Android_BuildNumber", PlayerSettings.Android.bundleVersionCode.ToString()) +
    28.             "}";
    29.  
    30.         string currentText = File.ReadAllText(finalPath);
    31.  
    32.         if (currentText != newText)
    33.         {
    34.             Debug.Log("Updated GameVersion.cs");
    35.  
    36.             File.WriteAllText(finalPath, newText);
    37.             AssetDatabase.Refresh();
    38.         }
    39.     }
    40.  
    41.     private static string FormatVar(string varName, string varValue)
    42.     {
    43.         return $"    public const string {varName} = \"{varValue}\";\r\n";
    44.     }
    45. }
     
    novaVision, _Adriaan, RaL and 9 others like this.
  29. Kazoos

    Kazoos

    Joined:
    Nov 28, 2012
    Posts:
    17
    So this works like a charm in local development, I assume this will work when building using Cloud Build too? (Just about to try this)
     
    berteodosio likes this.
  30. muhammad-qasim161

    muhammad-qasim161

    Joined:
    Apr 24, 2018
    Posts:
    3
    PlayerSettings.bundleVersion
    PlayerSettings.Android.bundleVersionCode
     
  31. Andrew-Kite

    Andrew-Kite

    Joined:
    Oct 16, 2014
    Posts:
    34
     
  32. waldgeist

    waldgeist

    Joined:
    May 6, 2017
    Posts:
    365
    This is awesome, thanks!

     
  33. SimonVigMillard

    SimonVigMillard

    Joined:
    Jul 25, 2018
    Posts:
    13
    Kazoos, did you verify whether this works in Cloud Build? I'm also unsure whether the build number is automatically incremented in every Cloud Build?
     
  34. myama

    myama

    Joined:
    May 2, 2014
    Posts:
    14
  35. votagus

    votagus

    Joined:
    Dec 13, 2016
    Posts:
    15
    The easiest way I found around it is to inject it during build time.
    First you need to have a scriptable object, let's say Assets/Config/Config.asset
    Code (CSharp):
    1. public class Config : ScriptableObject
    2. {
    3.     public string buildVersion;
    4. }
    And then during build modify the asset to add the build number.
    Code (CSharp):
    1. public class BuildProcess : IPreprocessBuildWithReport
    2. {
    3.    public int callbackOrder => 0;
    4.  
    5.    public void OnPreprocessBuild(BuildReport report)
    6.    {
    7.        string[] result = AssetDatabase.FindAssets("Config", new string[] { "Assets/Config/" });
    8.  
    9.        string path = AssetDatabase.GUIDToAssetPath(result[0]);
    10.        var config = (Config)AssetDatabase.LoadAssetAtPath(path, typeof(Config));
    11.  
    12.        config.buildVersion = Application.platform == RuntimePlatform.IPhonePlayer
    13.            ? PlayerSettings.iOS.buildNumber
    14.            : PlayerSettings.Android.bundleVersionCode.ToString();
    15.  
    16.        EditorUtility.SetDirty(config);
    17.        AssetDatabase.SaveAssets();
    18.        AssetDatabase.Refresh();
    19.    }
    20. }
    Of course during development this will not work, so this is the way I do it when trying to access it.
    Code (CSharp):
    1. string buildVersion = config.buildVersion;
    2. #if UNITY_EDITOR
    3. buildVersion = Application.platform == RuntimePlatform.IPhonePlayer
    4.     ? PlayerSettings.iOS.buildNumber
    5.     : PlayerSettings.Android.bundleVersionCode.ToString();
    6. #endif
     
  36. unity_A995563112384E60D4CA

    unity_A995563112384E60D4CA

    Joined:
    Oct 18, 2021
    Posts:
    1
    I cant believe that; after all this time, we still can't get the version number at runtime lol. So I decided to write the native code to do that, it is easy
    For android:
    Code (JavaScript):
    1. UnityPlayer.currentActivity.getPackageManager().getPackageInfo(UnityPlayer.currentActivity.getPackageName(), 0).versionCode
    For ios obj-c:
    Code (CSharp):
    1. [[NSBundle mainBundle] objectForInfoDictionaryKey: (NSString*)kCFBundleVersionKey];
     
  37. Johste

    Johste

    Joined:
    Jul 12, 2014
    Posts:
    18
    Thanks.

    Can you show us an example of how to use this from Unity for us thats not that well versed in writing native extensions?
     
  38. DantaliaN

    DantaliaN

    Joined:
    Oct 7, 2012
    Posts:
    18
  39. Oneiros90

    Oneiros90

    Joined:
    Apr 29, 2014
    Posts:
    77
    This is my solution, a runtime class that updates itself anytime the editor player settings are changed. You can easly add more parameters if you need (instructions in the comments)
    Code (CSharp):
    1. #if UNITY_EDITOR
    2. using System;
    3. using System.Collections.Generic;
    4. using System.IO;
    5. using System.Linq;
    6. using System.Runtime.CompilerServices;
    7. using System.Text.RegularExpressions;
    8. using UnityEditor;
    9. #endif
    10.  
    11. namespace Utils
    12. {
    13.     public static class RuntimePlayerSettings
    14.     {
    15.         // List here the player settings you want to retrieve at runtime.
    16.         // Mind that their value will be automatically overridden!
    17.         public const string iOSBuildVersion = "1";
    18.         public const int AndroidBundleVersionCode = 1;
    19.  
    20. #if UNITY_EDITOR
    21.  
    22.         // Map here your settings with the actual settings from UnityEditor
    23.         private static readonly Dictionary<string, Func<object>> RuntimeToEditorMapping = new()
    24.         {
    25.             { nameof(iOSBuildVersion), () => PlayerSettings.iOS.buildNumber },
    26.             { nameof(AndroidBundleVersionCode), () => PlayerSettings.Android.bundleVersionCode },
    27.         };
    28.  
    29.  
    30.         ///////////////////////////////////////////////////////////////////////
    31.         private class Updater : AssetModificationProcessor
    32.         {
    33.             private static readonly string playerSettingsPath = "ProjectSettings/ProjectSettings.asset";
    34.  
    35.             public static string[] OnWillSaveAssets(string[] paths)
    36.             {
    37.                 if (paths.Contains(playerSettingsPath))
    38.                     Update();
    39.                 return paths;
    40.             }
    41.  
    42.             public static void Update([CallerFilePath] string sourceFilePath = "")
    43.             {
    44.                 string text = File.ReadAllText(sourceFilePath);
    45.                 string newText = text;
    46.  
    47.                 foreach ((var valueName, var func) in RuntimeToEditorMapping)
    48.                     newText = SetValue(newText, valueName, func());
    49.  
    50.                 if (newText != text)
    51.                 {
    52.                     File.WriteAllText(sourceFilePath, newText);
    53.                     AssetDatabase.Refresh();
    54.                 }
    55.             }
    56.  
    57.             private static string SetValue(string text, string paramName, object newValue)
    58.             {
    59.                 var regexText = newValue is string ?
    60.                     @"((?<= " + paramName + @" = "")(.*)(?="";))" :
    61.                     @"((?<= " + paramName + @" = )(.*)(?=;))";
    62.                 var regex = new Regex(regexText, RegexOptions.Multiline);
    63.                 return regex.Replace(text, newValue.ToString());
    64.             }
    65.         }
    66.     }
    67. #endif
    68. }
     
    Last edited: Feb 22, 2022
  40. Dark-Table

    Dark-Table

    Joined:
    Nov 25, 2008
    Posts:
    315
    Thanks for this. Saved me a lot of time. It's very funny that this thread is old enough to go the movies by itself and there's still no way to get the bundle version code without a Java plugin or odd hack. *shrug emoji*
     
  41. glenneroo

    glenneroo

    Joined:
    Oct 27, 2016
    Posts:
    228
    It's been 12 years. Can you expose the field already? It can't be that hard can it? :)
     
    Jimaniki and AldeRoberge like this.
  42. AldeRoberge

    AldeRoberge

    Joined:
    Jun 23, 2017
    Posts:
    48
    Here's a version that does not need to have a GameVerison.cs script in the folder first :
    (Otherwise it throws a file not found exception)

    Code (CSharp):
    1. string currentText = "";
    2.  
    3.             if (File.Exists(finalPath))
    4.             {
    5.                 currentText = File.ReadAllText(finalPath);
    6.             }
    Also, it might be good to add a warning :

    Code (CSharp):
    1. newText += "\n // This code is automatically generated by VersionWriter. Do NOT edit!";
     
    Last edited: May 20, 2022
  43. xWiggle

    xWiggle

    Joined:
    May 18, 2022
    Posts:
    1
    Hi guys, I think I have an easy solution, this fixes the issue on the editor and shows correctly in the devices.

    Code (CSharp):
    1.  
    2. using TMPro;
    3. using UnityEngine;
    4.  
    5. #if UNITY_EDITOR
    6. using UnityEditor;
    7. #endif
    8.  
    9. public class VersionText : MonoBehaviour
    10. {
    11.     [SerializeField] private TMP_Text _text;
    12.  
    13.     private void OnValidate()
    14.     {
    15. #if UNITY_EDITOR
    16.         _text.text = "v" + Application.version + "." + PlayerSettings.Android.bundleVersionCode;
    17. #endif
    18.     }
    19. }
     
    Nith666, allan32, Extiward and 3 others like this.
  44. glenneroo

    glenneroo

    Joined:
    Oct 27, 2016
    Posts:
    228
    Please read the thread. 20 people have suggested this exact solution already and I'll be the 21st person to say: this. does. not. work. in. Builds. :)
     
    AiHimmel likes this.
  45. hungryish

    hungryish

    Joined:
    Jan 30, 2015
    Posts:
    1
    PrisedRabbit and glenneroo like this.
  46. Peecha

    Peecha

    Joined:
    Dec 2, 2013
    Posts:
    22
    Please read the code. Its actually viable and easy solution. :)
     
    glenneroo and JoeStrout like this.
  47. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,848
    Yeah, Peecha is right, @xWiggle's solution will work (if you attach this script to some prefab or scene object), and is darn simple. Use OnValidate to get the correct values at editor time, but serialize them on the object so you can retrieve them at runtime. Clever!
     
    glenneroo likes this.
  48. glenneroo

    glenneroo

    Joined:
    Oct 27, 2016
    Posts:
    228
    Sorry you are right! Sorry @xWiggle - my eyes glazed over when I read bundleVersionCode inside #if UNITY_EDITOR block. I just tested it and very clever! @hungryish 's solution also works for me.

    Still seems like Unity should be responsible and just expose this field instead of having people come up with all sorts of hacks that have appeared in this thread. It shouldn't need to be clever, it should be standard, easy to retrieve value. I can see the Version string in the Player settings and read it in code... so why not the Bundle Version Code?
     
    Peecha and JoeStrout like this.
  49. mahito2932

    mahito2932

    Joined:
    Nov 15, 2020
    Posts:
    94
    Can you show an example on how you did?
     
  50. Flexford

    Flexford

    Joined:
    Dec 8, 2016
    Posts:
    20
    You can do it only manually. The best way it's scriptable object, look at my solution.

    For use you need:
    1. download scripts in project(from message or zip file from attachment)
    2. create scriptable object "BuildRuntimeInfoSettings" in "Resource" folder by project context action ''Assets/Create/Build runtime info settings"
    3. (preffered) add this scriptable object in project setting -> other settings -> 'preload assets' list
    4. before build set versions to PlayerSettings.bundleVersion and PlayerSettings.Android.bundleVersionCode or PlayerSettings.iOS.buildNumber
    5. just build
    6. in runtime get values from BuidRuntimeInfo.Instance.Version or BuidRuntimeInfo.Instance.BuildId
    7. example BuildIdView.cs

    BuildInfoUtility/BuildRuntimeInfo.cs
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. namespace BuildInfoUtility
    4. {
    5.    [CreateAssetMenu(fileName = "BuildRuntimeInfoSettings", menuName = "Build runtime info settings")]
    6.    public class BuidRuntimeInfo : ScriptableObject
    7.    {
    8.       public static BuidRuntimeInfo Instance => _instance ??= LoadInfo();
    9.       private static BuidRuntimeInfo _instance;
    10.  
    11.       public string Version;
    12.       public string BuildId;
    13.  
    14.       private static BuidRuntimeInfo LoadInfo()
    15.       {
    16.          BuidRuntimeInfo result = Resources.Load<BuidRuntimeInfo>("BuildRuntimeInfoSettings");
    17.          if (result == null)
    18.          {
    19.             Debug.LogError("You need create asset file before build from context menu \"Assets/Create/Build runtime info settings\"");
    20.          }
    21.  
    22.          return result;
    23.       }
    24.    }
    25. }
    BuildInfoUtility/Editor/BuidRuntimeInfoPreprocess.cs
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEditor.Build;
    3. using UnityEditor.Build.Reporting;
    4.  
    5. namespace BuildInfoUtility
    6. {
    7.    public class BuidRuntimeInfoPreprocess : IPreprocessBuildWithReport
    8.    {
    9.       public int callbackOrder => default;
    10.  
    11.       public void OnPreprocessBuild(BuildReport report)
    12.       {
    13.          BuidRuntimeInfo settings = BuidRuntimeInfo.Instance;
    14.          if (settings != null)
    15.          {
    16.             settings.Version = PlayerSettings.bundleVersion;
    17.             settings.BuildId = GetBuildId();
    18.             EditorUtility.SetDirty(settings);
    19.             AssetDatabase.SaveAssetIfDirty(settings);
    20.          }
    21.       }
    22.  
    23.       private string GetBuildId()
    24.       {
    25. #if UNITY_ANDROID
    26.          return PlayerSettings.Android.bundleVersionCode.ToString();
    27. #elif UNITY_IOS
    28.          return PlayerSettings.iOS.buildNumber.ToString();
    29. #else
    30.          return default;
    31. #endif
    32.       }
    33.    }
    34. }
    BuildInfoUtility/BuildIdView.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3.  
    4. namespace BuildInfoUtility
    5. {
    6.    public class BuildIdView : MonoBehaviour
    7.    {
    8.       [SerializeField]
    9.       private Text _text;
    10.  
    11.       private void Reset()
    12.       {
    13.          _text = GetComponent<Text>();
    14.          _text.text = $"Build ID: ***";
    15.       }
    16.  
    17.       private void Start()
    18.       {
    19.          if (BuidRuntimeInfo.Instance != null)
    20.          {
    21.             _text.text = $"Build ID: {BuidRuntimeInfo.Instance.BuildId}";
    22.          }
    23.       }
    24.    }
    25. }
     

    Attached Files:

    ElasticSea likes this.