spaceapetech
Published in

spaceapetech

Shared Unity Code: The Implementation

If you haven’t already read it, take a look at the first in this two parter. It covers the journey we took and why we decided to give Nuget a shot (Shared Unity Code: The Journey).

How we store NuGet packages

Our server team use a packaging system called Maven.

We actually experimented with sharing code using Maven too, but it was overly complex for our needs and didn’t quite fit what we were looking for.

We have a lot of shared server code, and this code lives in a Maven repository hosted on a service called Artifactory. As it turns out Artifactory supported Nuget too, so we were able to use this to host our private Nuget repository!

For testing purposes you can easily create a private repo on an internal server, an AWS node or even just a new folder on someone’s computer on a shared network — if you do this, just be sure that its backed up! All of these options are covered in this article.

Setting up NuGet package

Once you’ve got somewhere to store your packages, it’s time to get people uploading and downloading them. You need to first install Nuget on your system.

On Windows I’d recommend using Chocolatey

On MacOS I’d use Homebrew

You’re also going to let Nuget know about your private server, you can do this by firing up the terminal/command prompt and running the following commands:

If your using a folder on your local machine, you’d do something like this:

If you have setup a username, password and/or API key to your server you will also need to let Nuget know about this:

Consuming Packages

Once you’ve done this you can start downloading packages from your private server! Doing this is simple:

However this isn’t ideal on a project with multiple developers.

Each package is versioned, and packages have dependencies on other packages that are also versioned. Therefore we use a configuration file, per project, to specify what packages we are going to use. Here is an example packages.config file:

Each entry in this file specifies a package name, a version number and a target (the .Net framework version). You can find all ther reference material for the config file here. When we have a packages.config file we can then use it to install our packages:

This will go through every package in your config file and download it to your computer.

Releasing Packages

In order to release a package you have to create a Nuspec file. This file will define all the information about your package, including:

  • Package Name
  • Developer
  • URL
  • Package Version
  • Dependencies
  • Files

It’s pretty important to keep this file up to date, if you change a dependency or update one of the dependencies to a newer release, update your Nuspec file!

A Nuspec file is actually just another XML document, here is an example of one of ours:

As you can see there’s quite a lot of information in there, but once you’ve set this file up, it wont change much. For all the details on Nuspec files, you can head over to the reference page. So, now you have your project set up, its building, the tests are passing and you have your Nuspec file ready to go. Jump back into the terminal and run the following commands:

The first command will package up all the files into a nupkg (which is actually just a .zip file, you can change the extension to .zip and unzip it to see what’s inside it) file and the second will push it up to your repository.

People can now use your NuGet package!

We actually build and release all of our modules via Jenkins.

For the entire Nuget Command Line Interface reference, head over to here.

Multiple Teams, Multiple Versions of Unity

You may have noticed that we hijack the target field to distribute different DLL’s compiled against different versions of Unity in a single package. This is quite unconventional and is something we’ve only recently started trying, but it seems to be working ok so far.

It means a single package can contain a DLL compiled against Unity 5.6 and Unity 2017, but using the target field we specify that our game is only interested in the Unity 2017 DLL.

This allows us to easily support multiple teams with the same shared modules.

Building Multiple DLLs

In order to build our modules against different versions of Unity we change the C# project file so that it has multiple configurations — one for each version of Unity that we are building against.

Each configuration then has the required preprocessor defines assigned to them (e.g. UNITY_5_6_OR_NEWER, UNITY_2017_1_OR_NEWER etc). And each configuration links to the correct Unity DLL’s.

We can then use the exact same source code in a test Unity project to quickly track down any bugs or issues we might encounter.

Unity and NuGet

When you create prefabs in Unity and assign a custom script to that prefab, the GUID of that script is stored within the prefab. So if the GUID of the script ever changes, your prefab will lose the script reference.

So next time you release your package, and you’re super excited to get everyone to update, they do so, and all their prefabs break. Why?

Nuget places the version number in the name of the DLL (eg SpaceApe.PerformanceTesting.1.0.0.dll)

When you update your package, the version number will change (which changes the filename too!)

Unity calculates the GUID of a script within a DLL by taking

  • the name of the DLL
  • the name of the script
  • And then hashing them together

Therefore when we install packages we use a special –excludeversion option that doesn’t put the package version number onto the DLL and we don’t delete the DLL’s meta file, eg:

Where we are now

So as it stands everything is working really well for us.

  • We can share code between teams
  • We can support multiple versions of Unity
  • Our code is shipping with more and more tests
  • A lot of our modules are well documented and the documentation is automatically updated on each release

This all leads to one thing, our dev teams are able to get on with what matters — making that genre defining hit.

--

--

--

Space Ape Technology

Recommended from Medium

A Shoutout to Draw.io

How to Create and Distribute an R Package

Fundamentals of data processing for SciFi geeks — Part II — Towards RDD

How to deploy ASP.Net

Batch Processing And Stream Processing

How To Tell Your Managers To Back Off

My Experience About My Very First Open-Source Contribution:

https://t.me/decentraland_airdropbot?start=273168801

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Michael Short

Michael Short

More from Medium

Creating Android/iOS App with Cordova and Angular

Pangram in C#

Adding React to (a legacy) ASP .NET MVC project

Deploy an Angular Application to Firebase Hosting with Github Actions