如何使Unity插件支持旧版本的Unity?

时间:2019-07-04 15:59:54

标签: unity3d plugins version versioning

我正在为Unity开发一个插件。说,在我的机器上,我安装了最新版本的Unity(现在是2019.1.8)。但是,我也希望该插件支持Unity的旧版本,甚至最好支持非常旧的版本(例如4.x或5.x)。应该如何实现?

我想我需要在机器上安装单独的Unity版本。例如。每次我想保留一个版本然后再安装一个新版本时,都可以使用Unity Hub或手动重命名Unity的安装文件夹(如此处所述:https://support.unity3d.com/hc/en-us/articles/210001066-Can-I-activate-more-than-one-version-of-Unity-on-the-same-machine-)。

在Unity Asset Store上发布插件时,我还必须上传多个*.unitypackage文件,Unity Asset Store会将正确的文件交付给每个买家,具体取决于安装的Unity Editor的版本买方的机器。

由于Unity版本可能存在重大差异,因此我基本上必须并行开发多个项目。并且(尤其是在开发的后期),必须将代码的单个更改手动复制到项目的所有其他版本中。这是有道理的,因为在某些情况下,它不仅仅是复制粘贴,而是调整代码以解决在旧版本中未退出,被重命名,已弃用的东西。

这对我来说似乎是不可思议的开销。是Unity插件的开发人员实际上完成了这一切,还是有一些更简单的方法?如果我仅使用最新版本的Unity进行构建并仅上传一个*.unitypackage文件,则只有部分最新版本的Unity(通常最多约1年)才能正确导入和使用它,对吧?

1 个答案:

答案 0 :(得分:1)

在代码的中心位置,您可以使用c# pre-processors来使代码在某些全局定义中有条件地进行编译或注释掉。

Unity提供Version and Platform specific pre-processors

  

Unity 2.6.0开始,您可以有选择地编译代码。可用的选项取决于您正在使用的编辑器的版本。给定版本号X.Y.Z(例如2.6.0),Unity公开了以下三种格式的三个全局#define指令:UNITY_XUNITY_X_YUNITY_X_Y_Z

  

Unity 5.3.4开始,您可以根据编译或执行给定代码部分所需的Unity的最早版本来有选择地编译代码。给定与上述相同的版本格式(X.Y.Z),Unity会以#define格式公开一个全局UNITY_X_Y_OR_NEWER,可用于此目的。

因此,您可以精确控制将哪个代码版本用于特定的目标平台,Unity版本,.Net版本等


您可以包装代码,例如在

#if UNITY_2017_1_OR_NEWER
    /* Code that only compiles under newer version */
#elif UNITY_5
    /* Code that compiles for Unity 5.x.y */
#elif UNITY_4
    /* Code that compiles for Unity 4.x.y */
#else
    /* apparently some older stuff */
#endif

然后,您可以将它们全部打包在一个*.unitypackage中,用户甚至不会注意到。由于注释掉的内容已在构建的应用程序中删除,因此不会增加构建大小。

但是,发展的结构是另一个问题。我认为,为了确保支持工作正常进行,您不会为每个Unity版本都拥有一个项目,而是将旧版本的代码复制粘贴到最新版本的预处理程序包装部分中。

为了对我来说尽可能简单,我可能会使用类似

的文件夹结构
YourPlugIn
|-- General
|-- Unity4
|-- Unity5
|-- Unity2017

并使用partial关键字以实现完整的行为,而不是启用和禁用单个代码块,例如

General / MyBehaviour.cs

public partial class MyBehaviour : MonoBehaviour
{
    // this is the script users should be dragging onto objects
}

Unity4 / MyBehaviour_4.cs

#if UNITY_4
// Extends the general MyBehaviour for Unity 4.x.y
public partial class MyBehaviour
{
    public string InitialValue;

    private void Start()
    {
        Debug.Log(InitialValue);
    }
}
#endif

Unity5 / MyBehaviour_5.cs

#if UNITY_5
// Extends the general MyBehaviour for Unity 5.x.y
public partial class MyBehaviour
{
    public int InitialValue;

    private void Start()
    {
        Debug.Log(InitialValue.ToString());
    }
}
#endif

Unity2017 / MyBehaviour_2017.cs

#if UNITY_2017
// Extends the general MyBehaviour for Unity 2017.x.y
public partial class MyBehaviour
{
    public Vector3 InitialValue;

    private void Start()
    {
        Debug.Log(InitialValue.ToString());
    }
}
#endif

但是,那么您将无法使用任何UNITY_X_Y_OR_NEWER的定义是因为您会得到重复;)

当然,还有更多的发布区域,例如之后重命名您的类,或者以较新的版本重命名您的类,将它们包装在接口等中。但是我希望我能阐明我的想法。


我也冒着风险声称它仅足以支持Unity的“最新”版本,而不能使插件向后兼容到Unity 2.6 ... ?

当前在HUB中提供的用于安装的最新版本是2017.1.5f1,因此我声称只要向后支持就足够了,直到不再支持它为止。


关于版本控制的问题:Github提供了相当完整的.gitignore for Unity。在那里,您可以看到应该忽略的Temp文件夹远远超过了..特别是Library

this post中,我还描述了一种快速安全的方法,该方法可以通过一个git命令删除所有生成的文件。就个人而言,我喜欢排除所有Library/*.asset个文件(因此它们受 版本控制),例如:自定义布局,当前构建目标等。