How to manage platform dependent code in a Unity project
Unity is a cross-platform game engine that provides great abstraction over the platform. Sometimes, however, you should use the platform API directly. In this article, we will consider available options that you have in such a situation, and the solution that we have adopted in our project.
There are common ways to manage the platform dependent code:
- Unity plugins https://docs.unity3d.com/Manual/Plugins.html
- Platform dependent compilation https://docs.unity3d.com/Manual/PlatformDependentCompilation.html
Unity plugins are great for scripts, but they don’t allow you to work with other assets (e.g. textures, prefabs, etc). Meanwhile, the platform dependent compilation is nice for simple cases. However, for a more complex part, it gets harder to write and change such code. IDE just ignores the disabled part, so it also doesn’t help.
For our project, we needed to build the system for 3 different platforms: HoloLens, Android and iOS. Android and iOS applications are nearly the same, so we just used the platform dependent compilation and plugins. Although HoloLens has a totally different user experience and some varying features, we decided to use the hidden assets feature of unity. https://docs.unity3d.com/Manual/SpecialFolders.html.
We divided platforms into two groups – mr and mobile (we also call them platforms). Code assets are divided into next folders: Mobile, Mr, Shared. All common assets are stored in the shared folder, and mobile or mr related assets are stored in the appropriate folders, respectively. All of these folders are enabled by developing the code in editor. We have a script that hides assets before building application.
We wrote the script on F#, but Unity C# script or any other language can be used as well.
High level structure of the script is next:
- Black list for each platform, e.g., a folder that should be hidden in order to build an application for the platform.
- Switch platform function that receives platform and adds “~” symbol to the end of each folder name from the black list.
- Default platform function - used for pre-commit git check in order to be sure that the repository doesn’t have any hidden assets.
So, we just can call it “platform.bat switch mr ..\Assets” in order to hide all assets that can’t and shouldn’t be compiled for the HoloLens build. After the build, we just call “platform.bat switch editor ..\Assets” in order to restore the hidden assets.
The code shouldn’t be committed when the platform is switched since a lot of folders will be treated by git as renamed (e.g. added “~” symbol). We use git hook in order to prevent any occasional commit of the switched project to repository. https://git-scm.com/docs/githooks#_pre_commit
# Validates platform of the project before commit # NOTE: we don't stach files before checking http://codeinthehole.com/tips/tips-for-using-a-git-pre-commit-hook/ if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # We allow to commit only system that in default platofomr/configuration isindefaultstate=$(fsi <Repository related path to script>/platform.fsx isdefault editor editor <Path to project root>/Assets | tail -n1) # Redirect output to stderr. exec 1>&2 if [ $isindefaultstate != "true" ] then cat <<\EOF Error: Attempt to commit code when project in not default state, should be editor platform and editor config. Reset system to the default state (via scripts or editor) and then try to commit again. EOF exit 1 fi
Obviously, the solution that we’ve reviewed in this article allows us to structure the platform dependent code in a clear way.