In general in your code you can use c# pre-processors in order to make code compile or commented out conditionally on some global defines.
Unity offers Version and Platform specific pre-processors
From Unity 2.6.0
onwards, you can compile code selectively. The options available depend on the version of the Editor that you are working on. Given a version number X.Y.Z (for example, 2.6.0), Unity exposes three global #define directives in the following formats: UNITY_X
, UNITY_X_Y
and UNITY_X_Y_Z
.
and
Starting from Unity 5.3.4
, you can compile code selectively based on the earliest version of Unity required to compile or execute a given portion of code. Given the same version format as above (X.Y.Z
), Unity exposes one global #define
in the format UNITY_X_Y_OR_NEWER
, that can be used for this purpose.
So you can exactly control which code version shall be used for which specific target platform, Unity version, .Net version etc
You can wrap your code e.g. in
#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
Then you can pack it all in one single *.unitypackage
and the user won't even notice. Since commented out stuff is stripped of in a built application it doesn't increase the build size.
The structure for development, however, is another question. I think in order to be sure that the support works you won't come arround having one project for each Unity version and copy paste the code for older versions into the pre-processor wrapped sections of the newest one.
In order to keep it as simple for me as possible I would probably use a folder structure like
YourPlugIn
|-- General
|-- Unity4
|-- Unity5
|-- Unity2017
and use the partial
keyword in order to implement complete behaviours instead enabling and disabling single code blocks e.g.
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
But then you can not use any of the e.g. UNITY_X_Y_OR_NEWER
defines because you would get duplicates ;)
Ofcourse there is a lot of more issue zones like e.g. renaming your classes afterwards or in newer version wrapping them in interfaces etc .. but I hope I made my idea clear.
I would also take the risk to claim that it should be enough to only support the "latest" versions of Unity and not make a Plug-In backwards compatiable down to Unity 2.6 ... who will still use that old stuff anyway?
Currently in the HUB the latest release that is offered for installation is 2017.1.5f1
so I'ld claim it is enough to have backwards support until that one and not any further.
To the question about version control: Github offers a pretty complete .gitignore
for Unity. There you can see that there is a lot more than the Temp
folder you should ignore .. especially the Library
.
In this post I also descriped a fast and secure way to remove all the generated files with one single git
command. Personally I like to exclude all Library/*.asset
files from the ignoring (so they are version controlled) as here some things like e.g. custom Layouts, the current build target etc are stored.