How to build a Unity project

steps summary

  • download unity + support platform pkgs
  • install all downloaded pkgs
  • run unity for about 10-30 seconds without -batchmode and -nographics flags → this will create CACerts for unity → needed to run unity
  • so sleep 30 and killall Unity
  • activate unity
  • run build script
  • return license
  • apk should be ready for deployment, iOS Xcode source requires archive step furthermore

:thinking::smirk: let’s build something cool

unity cmd-line tool - Macosx - installed from pkg

/Applications/Unity/Unity.app/Contents/MacOS/Unity

unity flags we’ll need

  • -batchmode
    • Run Unity in batch mode. This should always be used in conjunction with the other command line arguments, because it ensures no pop-up windows appear and eliminates the need for any human intervention. When an exception occurs during execution of the script code, the Asset server updates fail, or other operations that fail, Unity immediately exits with return code 1. Note that in batch mode, Unity sends a minimal version of its log output to the console. However, the Log Files still contain the full log information. Opening a project in batch mode while the Editor has the same project open is not supported; only a single instance of Unity can run at a time.
  • -executeMethod <ClassName.MethodName>
    • Execute the static method as soon as Unity is started, the project is open and after the optional Asset server update has been performed. This can be used to do tasks such as continous integration, performing Unit Tests, making builds or preparing data. To return an error from the command line process, either throw an exception which causes Unity to exit with return code 1, or call EditorApplication.Exit with a non-zero return code. To pass parameters, add them to the command line and retrieve them inside the function using System.Environment.GetCommandLineArgs. To use -executeMethod, you need to place the enclosing script in an Editor folder. The method to be executed must be defined as static.
  • -logFile <pathname>
    • Specify where the Editor or Windows/Linux/OSX standalone log file are written. Leave it empty or set /dev/stdout for outputting log to the console.
  • -nographics
    • When running in batch mode, do not initialize the graphics device at all. This makes it possible to run your automated workflows on machines that don’t even have a GPU (automated workflows only work when you have a window in focus, otherwise you can’t send simulated input commands). Please note that -nographics does not allow you to bake GI on OSX, since Enlighten requires GPU acceleration.
  • -password <password>
    • The password of the user, required when launching.
  • -projectPath <pathname>
    • Open the project at the given path.
  • -quit
    • Quit the Unity Editor after other commands have finished executing. Note that this can cause error messages to be hidden (however, they still appear in the Editor.log file).
  • -returnlicense
    • Return the currently active license to the license server. Please allow a few seconds before the license file is removed, because Unity needs to communicate with the license server.
  • -serial <serial>
    • Activate Unity with the specified serial key. It is good practice to pass the -batchmode and -quit arguments as well, in order to quit Unity when done, if using this for automated activation of Unity. Please allow a few seconds before the license file is created, because Unity needs to communicate with the license server. Make sure that license file folder exists, and has appropriate permissions before running Unity with this argument. If activation fails, see the Editor.log for info.
  • -username <username>
    • Enter a username into the log-in form during activation of the Unity Editor.

Read More: Unity - Manual: Command-line arguments

steps exploded
###Download required pkgs

#download unity pkg
curl -o ./unity.pkg http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorInstaller/Unity-5.5.0f3.pkg

#download android support platform
curl -o ./android.pkg http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorTargetInstaller/UnitySetup-Android-Support-for-Editor-5.5.0f3.pkg

#download iOS android support
curl -o ./ios.pkg http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorTargetInstaller/UnitySetup-iOS-Support-for-Editor-5.5.0f3.pkg

To find the version of unity pkg you need go to this page, and find the url of the pkg:

After you found the pkg’s url, you can get support platform pkgs like this:

  • The url I’ve found:
http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorInstaller/Unity-5.5.0f3.pkg
  • The {base url} will be:
http://download.unity3d.com/download_unity/38b4efef76f0
  • The {version} will be:
5.5.0f3
  • Accessing the actual version’s ini file: {base url}/unity-{version}-osx.ini
http://download.unity3d.com/download_unity/38b4efef76f0/unity-5.5.0f3-osx.ini

In the ini file, you will see fields like: [Android], [iOS], etc… And below the platform’s field you will find url= prefix, this url part is relative to {base url}

  • So your android platform support pkg’s url would be:
http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorTargetInstaller/UnitySetup-Android-Support-for-Editor-5.5.0f3.pkg

:sweat_smile:

##install downloaded pkgs

#install unity pkg
sudo -S installer -package ./unity.pkg -target / -verbose

#install unity android support pkg
sudo -S installer -package ./android.pkg -target / -verbose

#install unity iOS support pkg
sudo -S installer -package ./ios.pkg -target / -verbose

###Run Unity for initialisation

It is required when unity freshly installed. The first run will create CACert file, and anything required for unity. Seems like 10 secs is enough, and 15 secs is sure, but always check the log as you have to see the message at least: …300157 bytes written to /Users/vagrant/Library/Unity/Certificates/CACerts.pem :tada:

/Applications/Unity/Unity.app/Contents/MacOS/Unity -logfile &
sleep 15
sudo killall Unity

###Activate unity command line
For now unity only supports this on paid plans, where you have a serial number.

Set up these in your Secret Env Vars section:

  • UNITY_EMAIL
  • UNITY_PW
  • UNITY_SERIAL

then run:

/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -serial $UNITY_SERIAL -username $UNITY_EMAIL -password $UNITY_PW -logfile

If everything is ok with the activation, you will see the message:

LICENSE SYSTEM [2017328 15:27:7] License activated successfully with user: {UNITY_EMAIL}

:ok_hand:

###Build script
Can be your own if you have one already, but if you need one quickly just use this one (This how-to is based on our build script):

The build script must be included in your Assets folder within your Unity project.

###Run build script → build android apk or generate Xcode project
Android:

/Applications/Unity/Unity.app/Contents/MacOS/Unity -nographics -quit -batchmode -logFile -projectPath “$BITRISE_SOURCE_DIR” -executeMethod BitriseUnity.Build -androidSdkPath “$ANDROID_HOME” -buildOutput “$BITRISE_DEPLOY_DIR/mygame.apk” -buildPlatform android

The command above will build a debug apk.:lock: If you want to sign it, you can pass keystore details: :old_key:

  • -androidKeystorePath /path/to/your/keystore.keystore
  • -androidKeystorePassword YourKeystorePassword2017
  • -androidKeystoreAlias youralias
  • -androidKeystoreAliasPassword YourAliasPassword2017

The build script above detects these arguments, and will set these in your Build Settings:unlock:

iOS:

/Applications/Unity/Unity.app/Contents/MacOS/Unity -nographics -quit -batchmode -logFile -projectPath “$BITRISE_SOURCE_DIR” -executeMethod BitriseUnity.Build -buildOutput “$BITRISE_SOURCE_DIR/xcodebuild” -buildPlatform ios

The command above will generate your Xcode project if everything is successful, before you start building the Xcode project it is recommended to return the license used for the activation. It is required because of the seat management, if you don’t return that will cause some hassle to return it on Unity’s dashboard, or maybe you’ll need to contact Unity support and tell them to sort it out for you.

###Return license

/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -logFile -returnlicense

If you see Cancelling DisplayDialog: Information Unity license returned. - that’s great. :+1:t2:

###Finally
All you have to do is to build the {$BITRISE_SOURCE_DIR/xcodebuild} Xcode project, and then deploy your generated apk and ipa.

The project should be available at:

$BITRISE_SOURCE_DIR/xcodebuild/Unity-iPhone.xcodeproj

And the scheme should be:

Unity-iPhone

The rest is user-custom, setup your signing identities and all done! :white_check_mark:

###Sample workflow

---
format_version: 1.3.1
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
trigger_map:
- push_branch: "*"
  workflow: primary
- pull_request_source_branch: "*"
  workflow: primary
workflows:
  primary:
    steps:
    - activate-ssh-key@3.1.1:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone@3.4.2: {}
    - script@1.1.3:
        title: Download & Install Unity
        inputs:
        - content: |-
            #!/bin/bash
            set -ex

            #download unity pkg
            curl -o ./unity.pkg http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorInstaller/Unity-5.5.0f3.pkg

            #download android support platform
            curl -o ./android.pkg http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorTargetInstaller/UnitySetup-Android-Support-for-Editor-5.5.0f3.pkg

            #download iOS android support
            curl -o ./ios.pkg http://download.unity3d.com/download_unity/38b4efef76f0/MacEditorTargetInstaller/UnitySetup-iOS-Support-for-Editor-5.5.0f3.pkg

            #install unity pkg
            sudo -S installer -package ./unity.pkg -target / -verbose

            #install unity android support pkg
            sudo -S installer -package ./android.pkg -target / -verbose

            #install unity iOS support pkg
            sudo -S installer -package ./ios.pkg -target / -verbose
    - script@1.1.3:
        title: Activate Unity
        inputs:
        - content: |-
            #!/bin/bash
            # fail if any commands fails
            set -ex

            /Applications/Unity/Unity.app/Contents/MacOS/Unity -logfile &
            sleep 15
            sudo killall Unity

            /Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -serial $UNITY_SERIAL -username $UNITY_EMAIL -password $UNITY_PW -logfile
    - script@1.1.3:
        title: Build Android
        inputs:
        - content: |-
            #!/bin/bash
            # fail if any commands fails
            set -ex

            /Applications/Unity/Unity.app/Contents/MacOS/Unity -nographics -quit -batchmode -logFile -projectPath "$BITRISE_SOURCE_DIR" -executeMethod BitriseUnity.Build -androidSdkPath "$ANDROID_HOME" -buildOutput "$BITRISE_DEPLOY_DIR/mygame.apk" -buildPlatform android
    - script@1.1.3:
        title: Build iOS
        inputs:
        - content: |-
            #!/bin/bash
            # fail if any commands fails
            set -ex

            /Applications/Unity/Unity.app/Contents/MacOS/Unity -nographics -quit -batchmode -logFile -projectPath "$BITRISE_SOURCE_DIR" -executeMethod BitriseUnity.Build -buildOutput "$BITRISE_SOURCE_DIR/xcodebuild" -buildPlatform ios
    - script@1.1.3:
        title: Return Unity license
        is_always_run: true
        inputs:
        - content: |-
            #!/bin/bash
            # fail if any commands fails
            set -ex

            /Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -logFile -returnlicense
    - certificate-and-profile-installer@1.8.4: {}
    - xcode-archive@2.0.5:
        inputs:
        - workdir: "$BITRISE_SOURCE_DIR/xcodebuild"
        - project_path: "$BITRISE_SOURCE_DIR/xcodebuild/Unity-iPhone.xcodeproj"
        - scheme: Unity-iPhone
    - deploy-to-bitrise-io@1.2.9: {}

This all was done on Xamarin Stable with Xcode 7.3, on OS X 10.11 (El Capitan) - LTS Stack

Feel free to ask any questions!
:rocket::tada:

2 Likes

I believe the Return Unity license task needs a is_always_run: true to avoid locking the serial when a build fails.

2 Likes

Hi @julio-pushstart!

Exactly! Just updated the yml in the OP, good catch! Thanks

1 Like

Is there a solution to cache Unity and the Cache Server of the Unity project?
This would decrease build time dramatically.

2 Likes

Hey!

Not yet, but very good idea! If you have the time to research a little, how you can cache stuff on your local machine, then share here the info, that would be awesome!

1 Like

How long does the download&install unity step takes in average when run in bitrise?

Hey @guperrot!

In our tests the minimum time was 206s and the maximum 494s. It is the same script that downloads and installs 5.5.0f3 editor, ios and android support pkgs. :slightly_smiling_face:

1 Like

Ok thanks :grinning:

2 Likes

Hey,

I’ve followed these steps and have been successful in building Unity projects with Bitrise! Thanks for sharing.

Downloading and installing the required applications wasn’t taking too long for my builds, maybe 4 - 6 minutes (manageable). However, because we are not including the Library folder of our Unity project under Git version control, the actual building of the app took 30+ minutes, due to needing to rebuild the asset database, compile shaders, etc with every build.

I have been able to setup Bitrise Cache:Pull / Cache:Push steps to cache that asset database, which helped tremendously! Builds back down in the 7-8 minutes, which is awesome.

I am trying to include the installed applications in my cache step now to save even a bit more time, but running into issues because the install script uses sudo to install the applications, and they are installed to /Applications/. When the Cache:Push step runs, I get this error:

Failed to generate files map, error: open /Applications/Unity/Unity.app/Contents/Resources/PackageManager/Editor/Packman_Temp/com.unity.ads-2.0.3/package: permission denied

This makes the Cache:Push step fail and it then doesn’t push the asset database changes either.

Do you know if there is a workaround to this? Would it be possible to add something to my build cache that’s located outside $BITRISE_SOURCE_DIR? Can I change the permissions of that directory or install / move the Unity application directory to a location that can be included in my cache?

Thanks a lot, let me know if I can provide more information.

1 Like

Hey @thorsonmscott! :wave:

Glad to hear it is working fine for your project! Yeah, caching library dir is one of a great solutions.

A script step with some kind of sudo chmod commands sounds like a quick solution for me, however I don’t recommend caching the installed Unity because that would cause a lot of overhead for the cache steps. Also a big-sized cache (which is a tar archive) makes the results foolish, because maxed out network peaks can cause 100x slower cache operation than with a smaller cache archive.

I think you are near to the perfect configuration. (Sounds like for me) :+1:

Could you please post your bottom summary list with the step names and times for our record and investigation?

Thanks in advance! :blush:

1 Like

Thanks a lot for this.
Quick question, is we are on a Unity free plan, is it impossible to make it work in Bitrise? Or we could just skip the activation step?

Thanks

Hi @cyril94440,

Unfortunately, you’d need a license key to use Unity, you won’t be able to do so with the free version. :disappointed:

1 Like

These guys… Haha thanks for your very quick answer!

Thanks for the tips on how to build the unity project in bitrise, but i am having massive issues trying to export the actual iOS app to crashlytics. I’m failing at the first hurdle of signing the app. I have tried using the bitrise iOS provisioning steps and also fastlane match but neither work. Has anyone had any luck with these?

Hey @adamjsutcliffe!

We’re more than happy to look into these issues, can you contact us about them on our on-site chat, or on a different #issues:build-issues thread?

Hi,
have anyone tried(sucessfully) build android with Unity 2018.1 and above?

Hi! I use the 2018.3.6 version and I get the error on the “Activate unity command line” step. Error:

Launching external process: /Applications/Unity/Unity.app/Contents/Resources/PackageManager/Server/UnityPackageManager
ListPackages failed, output: {
“name”: “unity-editor”,
“version”: “5.7.0”,
“problems”: [
“missing: unity-editor-home@2.2.1, required by unity-editor@5.7.0”,
“missing: unityeditor-cloud-hub@0.0.15, required by unity-editor@5.7.0”,
“missing: unityeditor-collab-toolbar@0.7.16, required by unity-editor@5.7.0”
],
“dependencies”: {
“unity-editor-home”: {
“required”: “2.2.1”,
“missing”: true
},
“unityeditor-cloud-hub”: {
“required”: “0.0.15”,
“missing”: true
},
“unityeditor-collab-toolbar”: {
“required”: “0.7.16”,
“missing”: true
}
}
}

Could you help me?

Hi @Stylish!

Sorry to hear about the issue, can you please either create a separate #issues:build-issues thread or contact us on our on-site chat instead?

Hello, is it possible with the Unity build path to build for PC or just iOS/Android?

Hi @chrisklingler!

This is a guideline on how to approach Unity projects on Bitrise, we’re currently working on our official support. Bitrise was made for mobile apps and the same goes for the tools we develop and maintain. MacOS apps are supported with certain steps, but we don’t have a Windows environment for instance.