在Unity3d中获取应用程序包版本

17

问题简单,但似乎很难找到答案。

我正在制作一款Android和iOS游戏。 我想提取应用程序的版本(即"2.0.1"),以便在App Store / Google Play上有新版本时显示弹出窗口。

有人知道如何以编程方式实现这一点吗?


捆绑包在哪里:在您自己的服务器上还是作为应用内购买的托管内容?捆绑包的责任是什么?是真实资产还是只是版本信息,以触发应用程序的更新? - Kay
如果您仍然想要获取捆绑版本的解决方案,请查看我下面更新的答案。 - Kay
我已经发布了这个游戏,但将来的项目中会再次查看它!谢谢! - Sunkas
@Sunkas的采纳答案已经过时了 - 你能否更改采纳答案?谢谢。 - jhabbott
我已经更改了被接受的答案。但是,我还没有验证它是否正确。这是在StackOverflow上正确的方式吗? - Sunkas
3个回答

17
过时:尽管此答案在撰写时是完全有效的,但它包含的信息已过时。现在有更好的方法来做到这一点,请参见此答案。出于历史原因,已保留该答案。

更新

我大幅改进了下面描述的解决方案,并制作了一个开源项目(MIT许可证),托管在github上。一眼看去,它不仅提供了访问当前运行的应用程序捆绑版本的方法,还以相当方便的方式跟踪以前捆绑版本的历史记录-至少需要安装插件或进行一些手动调整。
所以请看:

BundleVersionChecker at github
使用方法和更多细节


我刚刚发现另一个非常方便的解决方案。需要2个类:

第一个是检查当前PlayerSettings.bundleVersion的编辑器类。我称之为BundleVersionChecker,并且它必须放置在Assets/Editor中。它作为代码生成器,仅在包版本更改时生成一个非常简单的静态类,其中只包含一个版本字符串:

using UnityEngine;
using UnityEditor;
using System.IO;

[InitializeOnLoad]
public class BundleVersionChecker
{
    /// <summary>
    /// Class name to use when referencing from code.
    /// </summary>
    const string ClassName = "CurrentBundleVersion";

    const string TargetCodeFile = "Assets/Scripts/Config/" + ClassName + ".cs";

    static BundleVersionChecker () {
        string bundleVersion = PlayerSettings.bundleVersion;
        string lastVersion = CurrentBundleVersion.version;
        if (lastVersion != bundleVersion) {
            Debug.Log ("Found new bundle version " + bundleVersion + " replacing code from previous version " + lastVersion +" in file \"" + TargetCodeFile + "\"");
            CreateNewBuildVersionClassFile (bundleVersion);
        }
    }

    static string CreateNewBuildVersionClassFile (string bundleVersion) {
        using (StreamWriter writer = new StreamWriter (TargetCodeFile, false)) {
            try {
                string code = GenerateCode (bundleVersion);
                writer.WriteLine ("{0}", code);
            } catch (System.Exception ex) {
                string msg = " threw:\n" + ex.ToString ();
                Debug.LogError (msg);
                EditorUtility.DisplayDialog ("Error when trying to regenerate class", msg, "OK");
            }
        }
        return TargetCodeFile;
    }

    /// <summary>
    /// Regenerates (and replaces) the code for ClassName with new bundle version id.
    /// </summary>
    /// <returns>
    /// Code to write to file.
    /// </returns>
    /// <param name='bundleVersion'>
    /// New bundle version.
    /// </param>
    static string GenerateCode (string bundleVersion) {
        string code = "public static class " + ClassName + "\n{\n";
        code += System.String.Format ("\tpublic static readonly string version = \"{0}\";", bundleVersion);
        code += "\n}\n";
        return code;
    }
}

第二个类名为CurrentBundleVersion。它是由BundleVersionChecker生成的简单类,可从您的代码访问。每当其版本字符串与PlayerSettings中找到的版本字符串不相等时,它将被BundleVersionChecker自动重新生成。

public static class CurrentBundleVersion
{
    public static readonly string version = "0.8.5";
}

由于它是生成的代码,您不必关心它,只需将其提交到版本控制系统中即可。

因此,在您的代码中的任何地方,您只需要编写:

if (CurrentBundleVersion != "0.8.4") {
    // do migration stuff
}

我目前正在开发一款更复杂的版本。这个版本将包含一些版本跟踪功能,以执行以下操作:

if (CurrentBundleVersion.OlderThan(CurrentBundleVersion.Version_0_8_5) // ...


非常好,谢谢! - Mic
将Unity升级到5.3.2f1和MonoDevelop升级到5.9.6后,它停止工作了。现在我在BundleVersionChecker.cs中收到一个构建错误:The name 'CurrentBundleVersion' does not exist in the current context. 在Unity中关于编辑器和游戏类之间符号暴露方面是否有所改变? 我尝试在定义类CurrentBundleVersion之前添加[InitializeOnLoad](在UnityEditor命名空间中),但没有帮助:( - Mic
好的,我成功解决了构建错误问题。具体方法是在BundleVersionChecker()构造函数中不检查版本更改,而是直接调用CreateNewBuildVersionClassFile(PlayerSettings.bundleVersion)。我认为它每次Unity编辑器窗口获得焦点时都会被调用,对性能没有太大影响。 - Mic
抱歉评论中缺少代码格式:static BundleVersionChecker () { string bundleVersion = PlayerSettings.bundleVersion; Debug.Log ("正在替换文件 "" + TargetCodeFile + "" 中的包版本 " + bundleVersion); CreateNewBuildVersionClassFile (bundleVersion); } - Mic
对于Unity 2018.x.x,我刚刚创建了两个CurrentBundleVersion文件,分别为CurrentBundleVersionEditorCurrentBundleVersion。我会同时更新它们,并在运行时或编辑器中使用其中一个。 - mayo

14

7

已过时:虽然本答案在编写时完全有效,但它包含的信息已经过时了。现在有更好的方法,请参见此答案。为了历史原因保留了答案,请在进行评分之前考虑这一点。

总之:不能直接从Unity中获取应用程序捆绑版本。

实际上,有一个名为PlayerSettings.bundleVersion的函数可以读取您在播放器设置中设置的数字,但不幸的是,它是一个编辑器类函数,因此您无法在运行时使用它。(实际上您可以在Xcode中更改此数字,因此在Unity的播放器设置中设置的数字可能是错误的)。

一种简单的方法是在代码中编写您的版本号,并在提交和更新您的应用程序时更新该数字。这有点危险,因为您可能会在发布之前忘记这样做。因此您可能需要一个检查列表。

另一种方法是编写一个插件。 Xcode SDK有一种方法可以从info plist中获取应用程序的版本。 您可以将其返回给Unity以满足您的目的。

[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接