When developing Unity games, you will find that there is lots of code you want to share between all of your projects. It is possible to share these through symbolic links in your filesystem or importing them into the project through a custom package. However, why not go one step further and separate these shared scripts out into open source libraries for other people to share.
I have created open source Android libraries before, but when it came to doing the same for Unity it was all very new and there was only a small amount of guidance available online. Here I will document the whole process including setting up source control, writing unit tests, setting up continuous integration and building the final package.
Before you begin, make sure your Unity editor is setup properly for keeping your project in Git source control. If you haven’t done this yet, then please check out my article below which tell you more.
Prepare Your Unity Project For Git
When you start writing the code for your package, you will find that there isn’t really any form of enforced project structure. A clear project structure that keeps things nice and organised is usually the best way to go, which is especially important if other people need to read through your code. If you are interested in how I go about structuring my projects, then please check out my article below.
A Project Structure for Your Open Source Unity Packages
When it comes to the language to write scripts in, I always go with C#. It seems to be the most common in other Unity projects I have looked at and its similarities to Java (and other Object-Oriented languages) make it quite easy to pick up.
When it comes to C# classes, it is a really good idea to put all of your classes within your own namespace. This avoids there being name clashes with other classes the user of your package has in their project, much like packages in Java.
namespace MyCompanyName.MySuperLibrary {
using SomeOtherNamespace;
public class MyMainClass {
...
}
}
Anyone who wishes to use your class will either reference it with MySuperLibrary.MyMainClass or they can add using MySuperLibrary; to the top of their class. There is an MSDN article to explain how best to name your namespaces.
You can see above that the using statements are within the namespace declaration. This ensures that in the case of a class existing in multiple namespaces, the one you intended to use is the one the compiler chooses.
There is a trend to focus on writing clean code that is self-documenting instead of relying on comments. However, it is still standard practise for libraries to have documentation on their public API methods. This allows documentation guides to be generated and for IDEs to show you how to use a method when you try to call it. It is therefore suggested you do this for any public methods and classes within your package.
<a href="https://medium.com/media/14d8459402116111eb3181a29c20a7f2/href">https://medium.com/media/14d8459402116111eb3181a29c20a7f2/href</a>
Most C# IDEs will have a keyboard shortcut to add the documentation block (or an available plugin can add this functionality).
Writing unit tests for your C# code couldn’t be much easier, thanks to the Unity Test Tools built right into the editor. For each class you want to test (which is all of them of course), simply create a class with the same name but with the suffix Test in your test sources directory. A common practice is to also add a test suffix to the namespace for the test classes. To match my project structure I therefore add the suffix .UnitTests.
The tests themselves are written using standard NUnit, with the [Test], [SetUp] and [TearDown] attributes, along with the NUnit assertions.
<a href="https://medium.com/media/43813edbaee05184eb8dbfde4d9a59af/href">https://medium.com/media/43813edbaee05184eb8dbfde4d9a59af/href</a>
To run the unit tests, just switch to the Unity editor and open the test runner at Window -> Editor Tests Runner. Feel free to attach the floating window, to make it easier to come back and run the tests again.
In this window, you have access to Run All, Run Selected and Rerun Failed. When you run the tests you will see which ones, if any, have failed and if there is a failed test there will be a trace underneath to help you get them all passing.
Now that you have code written for your library and some tests checking that it works, the next step is to get your continuous integration setup. In the case of a Unity project this will involve creating a few simple scripts, for Travis to execute.
To begin with you will need to download and install the Unity editor.
<a href="https://medium.com/media/549f0dfd343fe9b2156e81f4071d8c20/href">https://medium.com/media/549f0dfd343fe9b2156e81f4071d8c20/href</a>
If you need to install support for any additional platforms you can add these at the bottom. For example:
install "MacEditorTargetInstaller/UnitySetup-Windows-Support-for-Editor-$VERSION.pkg"
To find out the name of any packages you need, simply go to the below URL. For the $PLATFORM, enter osx for the Mac environment.
$BASE_URL/$HASH/unity-$VERSION-$PLATFORM.ini
http://netstorage.unity3d.com/unity/649f48bbbf0f/unity-5.4.1f1-osx.ini
The next script you need will be to build the code, the best way to ensure it is all working is by building a player for one of the platforms.
<a href="https://medium.com/media/904866bd9006ba1d7500aab3f49455a4/href">https://medium.com/media/904866bd9006ba1d7500aab3f49455a4/href</a>
The script detailed above will build the project, output any Unity logs to the console, before finishing with 0 for success and 1 for failure.
The final step will be to export your assets to a Unity package. The script can be used to test the process works as well as to create the package to give to your users.
<a href="https://medium.com/media/a2f8bc67f7c667cabd52a50c18e38742/href">https://medium.com/media/a2f8bc67f7c667cabd52a50c18e38742/href</a>
Within the exportPackage argument, you can specify as many paths as you would like by specifying each as a separate string argument. In the script above only one path is included in the package.
The final piece of the puzzle, is to put together the Travis script using the scripts written above. This sits at the root of the project and should be named .travis.yml.
<a href="https://medium.com/media/f4bcb5e020f169b9b115c8bd15111962/href">https://medium.com/media/f4bcb5e020f169b9b115c8bd15111962/href</a>
At the top, I have specified that the language is Objective-C. This is just to ensure that the environment is setup for Mac and iOS. The osx_image and rvm can be changed to whichever versions you want to use.
Before using any of the scripts written above, chmod is used to ensure they are executable. Once this has happened, the install phase can run, which consists of running the install-unity script.
After the editor has been installed, the bulk of the CI job consists of building a player with build and then running all of the editor tests with run-tests. If both of these succeed then it will check the package can be exported correctly.
One option for releasing your package is through the Unity Asset Store, which will be documented very well by Unity Technologies themselves. Here I am going to offer a simple way to release your packages, so that users can download them and include them into their projects.
<a href="https://medium.com/media/4f3ee60b008f495611a51bbefd0e2225/href">https://medium.com/media/4f3ee60b008f495611a51bbefd0e2225/href</a>
The script accepts the version name as a command-line argument and will then place a named copy of the package into the release directory. This can then be hosted wherever you wish or could be committed to your master branch.
With the package in your repository, you should make sure you tag the commit in which you added it with the version name and then prepare a GitHub release. This will allow people to easily go back to each version of your package and it allows you to tell people about new versions of the package.
My first Unity package, PowerPrefs, uses everything discussed above, so if you are interested in seeing it in practice then please check it out.
andrewlord1990/unity-powerprefs
I hope you have found this useful, please let me know if have ideas for any improvements to the process. Good luck creating your own open source Unity packages!