Building for iOS targets in Unity
This page describes the required steps for a SpatialOS Unity project to support iOS build targets.
Preparation
This guide assumes that you have an existing SpatialOS project, which you are intending to add iOS support using Unity.
First, determine if you have automatically generated build scripts for Unity turned on:
- Locate the
workers/unity
folder of your SpatialOS project. - Open
spatialos.UnityClient.worker.json
in a text editor. - Open
spatialos.UnityWorker.worker.json
in a text editor. - If either of the above files have the line
"generated_build_scripts_type" : "unity"
, automatically generated build scripts are turned on.
Next, check if the following three files already exist in the workers/unity
folder of your SpatialOS project:
spatialos.unity.client.build.json
spatialos.unity.worker.build.json
spatialos_worker_packages.json
Do you see all three of those files?
YES, I see all three of those files:
Remove the line
"generated_build_scripts_type" : "unity"
from BOTH of the build scripts (spatialos.UnityClient.worker.json
andspatialos.UnityWorker.worker.json
) as described above.This will prevent them from being over-written each time you build.
NO, I don’t see any of those files:
- Run
spatial worker build
once - The files should now be generated.
Remove the line
"generated_build_scripts_type" : "unity"
from BOTH of the build scripts i.e.spatialos.UnityClient.worker.json
andspatialos.UnityWorker.worker.json
as described above.This will prevent them from being over-written each time you build.
- Run
1. Modify your UnityClient
build scripts
Add an additional build step to your Unity worker’s build configuration:
- Locate the
workers/unity
folder of your SpatialOS project. - Open
spatialos.unity.client.build.json
in a text editor. - By default, you will have a task named “Codegen” with several steps, e.g., “Dependencies”, “C# standard library”, “C#”, etc.
- Go to the last step, which should be “Compile generated scripts”.
Add a new step with the following content:
{ "name": "Compile serializers for generated schemas", "description": "The restrictions on iOS prevent runtime code-generation of schema serializers. Precompile these serializers into a separate DLL that can be included for iOS compatibility.", "arguments": [ "invoke", "unity", "Improbable.Unity.EditorTools.Build.ProtoMessagesTypeModelPrecompiler.Precompile" ] }
You can also download an example JSON file.
2. Modify your worker packages
Add an additional worker package to your Unity worker’s worker packages JSON file:
- Locate the
workers/unity
folder of your SpatialOS project. - Open
spatialos_worker_packages.json
in a text editor. - By default, you would have several targets specified, each with a “path”, “type”, and a list of “packages”.
Add three new targets by using the following content:
{ "path": "Assets/Improbable/Sdk/Editor/Addons", "type": "unity", "packages": [ { "name": "Improbable.Unity.EditorAddOn.iOSBuildTools" } ] }, { "path": "Assets/Plugins/Improbable/darwin_ios-arm_dll", "type": "worker_sdk", "packages": [ { "name": "core-dynamic-arm-ios" } ] }, { "path": "Assets/Plugins/Improbable/darwin_ios-x86_64_dll", "type": "worker_sdk", "packages": [ { "name": "core-dynamic-x86_64-ios" } ] }
You can also download an example JSON file.
3. Build your project
To apply the changes from the previous steps, build your project:
- In the terminal, build your project by running
spatial worker build
. - Wait until the build process completes successfully and without any errors.
- Navigate to the folder
workers/unity/Assets/Improbable/Sdk
. - You should see three sub-folders,
Dll
,Editor
, andSrc
. - In the
Dll
sub-folder, verify that the fileGenerated.Code.Serializer.dll
is present. - In the
Editor
sub-folder, verify thatAddons/iOSBuildTools
is present.
4. Modify your Unity project
Open your project in Unity. You’ll need to make the following changes to prepare the application for iOS build targets.
Add/modify the linker configuration
As Unity automatically strips out code and assemblies for iOS workers, it is important to add a linker configuration
link.xml
; it prevents some code, for example Protobuf serialization/deserialization method calls, from being stripped out
by Unity.
For more information about iOS Worker optimizations and how to customize the linker configuration, refer to the Unity Documentation
- In Unity, add a file called
link.xml
into theAssets
folder, if not already present. The contents of this file should contain the following:
<linker> <assembly fullname="Generated.Code" preserve="all"></assembly> <assembly fullname="Generated.Code.Serializer" preserve="all"></assembly> <assembly fullname="Improbable.WorkerSdkCsharp" preserve="all"></assembly> <assembly fullname="protobuf-net" preserve="all"></assembly> </linker>
You can also download this
link.xml
.
Modify the Bootstrap.cs
game object
in Unity, open the
ClientScene
orUnityClient
scene found in the Assets folder of the project navigator.Click on the
GameEntry
game object in the scene hierarchy.Open the
Bootstrap.cs
MonoBehaviour script by double clicking on the script in the Inspector.By default, you will see the line:
SpatialOS.ApplyConfiguration(Configuration);
Delete and replace it with the following code snippet:
List<string> commandLineArguments = null; #if UNITY_IOS // Set to the name of your SpatialOS project here. // This should match the project name as specified in spatialos.json const string APP_NAME = "<insert_your_project_name_here>"; commandLineArguments = new List<string>(System.Environment.GetCommandLineArgs()); commandLineArguments.AddRange(new List<string>() { "+" + CommandLineConfigNames.AppName, APP_NAME }); Improbable.Worker.ProtobufTypeModel.Serializer = new Generated.Code.Serializer(); #endif SpatialOS.ApplyConfiguration(Configuration, commandLineArguments);
IMPORTANT: Make sure to set the
APP_NAME
constant to your project name. This should match the project name as specified inspatialos.json
.In the
Bootstrap (Script)
panel of the Inspector:Click to expand
Configuration
->Debugging
.For
Infra Service URL
:If testing locally (
spatial local launch
), set to:http://127.0.0.1:21000
If testing against a deployment (
spatial cloud launch
), set to:https://api.spatial.improbable.io
Click to expand
Configuration
->SpatialOS Application
.- For
Assembly Name
:- If testing locally (
spatial local launch
), set to:local_assembly
- If testing against a deployment , leave it blank and not set.
- If testing locally (
- For
Login Token
:- If testing locally (
spatial local launch)
), leave it blank. - If testing against a deployment, set it to a valid login token.
- If testing locally (
- For
This image highlights the key settings required on your Bootstrap game object:
5. Build the iOS Client Worker
This section outlines several additional modifications required to configure Unity correctly for SpatialOS and iOS.
Modify the iOS Worker Build Settings
The following build settings are recommended for compatibility with SpatialOS.
Within Unity, access the build settings via:
File
->Build Settings...
Under
Platform
, selectiOS
such that it is highlighted.Click on
Player Settings...
. This should show thePlayer Settings
in the Inspector.Click the icon to make sure that you are in the
Settings for iOS
tab:Expand the
Other Settings
section:
Configure
Other Settings
with the following settings:- Configuration:
- Scripting Backend:
IL2CPP
- Target SDK:
Device SDK
orSimulator SDK
- Target minimum iOS Version:
10.2
or higher - Allow downloads over HTTP (nonsecure): Checked
- Architecture:
Universal
(Device) orx86_64
(Simulator) - Scripting Define Symbols:
CROSS_PLATFORM_INPUT;MOBILE_INPUT
- Scripting Backend:
- Optimization
- API Compatibility Level:
.NET 2.0
- Strip Engine Code: Unchecked
- Script Call Optimization:
Slow and safe
- API Compatibility Level:
When you’re finished, your settings should look like this:
- Configuration:
Building the iOS Worker
Return to the Build Settings panel:
(Optional) It is useful to set
Run in Xcode as
to Debug and to checkDevelopment Build
. This will enable full stack traces to be visible when running from Xcode.Click Build.
When the dialog prompts you to choose a location to save the project:
Navigate to
workers/unity/build/worker/
Hint: Click on the little arrow next to
Save As
to expand the panel to enable you to browse.Create a folder called
UnityClient@iOS
, if it doesn’t already exist.Click to select and highlight the
UnityClient@iOS folder
Under
Save As:
, enter the nameUnityClient@iOS
.Click Save.
Note: The following image should resemble what you see on your screen. By making sure that the
UnityClient@iOS
folder is selected (blue), the generated Xcode project will be placed in a folder within theUnityClient@iOS
folder.That is, your Xcode project file will be located in
workers/unity/build/worker/UnityClient@iOS/UnityClient@iOS/Unity-iPhone.xcodeproj
. The repeated folders are intentional! This will help maintain the same conventions and structure that standalone Unity workers have.(Optional) Having done the above, you can now also specify
iOS
as a build target in yourplayer-build-config.xml
file. This will automatically build an iOS worker with the last saved build settings you have in Unity.
6. Update Xcode Build Settings
Once Unity has completed building the iOS worker, you will need to use Xcode to build and run the application on your iOS device or simulator. There are several settings to configure in the generated Xcode project. You have two options to make these changes:
Option 1: Use the
Improbable->iOS->Update Xcode Build Settings
menu in Unity:This is the recommended approach. After doing so, you may then skip straight to Step 7: Codesign libCoreSdkDll.dylib.
Option 2: Follow the instructions outlined in the rest of this section.
Modify the Xcode project settings
Reminder: If you chose Option 1 above, you may skip this section and go straight to Step 7: Codesign libCoreSdkDll.dylib.
- Open the Xcode project located in:
workers/unity/build/worker/UnityClient@iOS/UnityClient@iOS/Unity-iPhone.xcodeproj
In the
Project Navigator
located on the left panel of Xcode, click onUnity-iPhone
:On the main pane of Xcode, click on Unity-iPhone listed under
Targets
(notProject
!)Click on the
Build Settings
tab.Make sure that both
All
andCombined
tab settings are active. Then, make the following changes:- Architectures
Architectures
:x86_64
(Simulator) ORarmv7,armv7s,arm64
(Device).Base SDK
: Change toLatest iOS
from the dropdown menu (e.g.,Latest iOS (iOS 10.2)
).Valid Architectures
:x86_64
(Simulator) ORarmv7,armv7s,arm64
(Device).
- Linking
Runpath Search Paths
: Add@executable_path
.
- Search Paths
Library Search Paths
: Remove all double quotes from the entries listed there. e.g.,$(SRCROOT)/Libraries
should be just$(SRCROOT)/Libraries
- ENABLE_BITCODE
- Set to
NO
- Set to
- Architectures
Hint: Use the search bar to help find these settings.
Add libCoreSdkDll.dylib
to the project
Locate the appropriate platform version of the
libCoreSdkDll.dylib
in your project.- For iOS Simulators, locate it in
workers/unity/Assets/Plugins/Improbable/darwin_ios-x86_64-dll/
. - For iOS Devices, locate it in
workers/unity/Assets/Plugins/Improbable/darwin_ios-arm-dll/
.
- For iOS Simulators, locate it in
Copy the selected
libCoreSdkDll.dylib
into the folder:unity/build/worker/UnityClient@iOS/UnityClient@iOS/Data
.You can do this also by drag-and-dropping the file into the
Data
folder in the Xcode project navigator. The image below shows how your project and file system should look:
7. Codesign libCoreSdkDll.dylib
Codesign the libCoreSdkDll.dylib
in your project using your Apple Certificates. This can be done by running the following
command in the terminal:
codesign -s "iPhone Developer" <path_to_project>/workers/unity/build/worker/UnityClient@iOS/UnityClient@iOS/Data/libCoreSdkDll.dylib
8. Build and run Xcode project
- In Xcode, start building your project using the
Product->Build
menu or by usingCMD+B
. If you observe build errors related to
Unknown type names
(for example,OrConstraint_t1672328221
), this is due to a bug in Unity’s IL2CPP code generation.- To fix these issues manually, and learn more about what causes them, refer to our Troubleshooting guide.
To fix these issues automatically, use this bash script:
- Download the script:
fix-il2cpp-xcode.sh
- Place it in your
<path_to_your_project>/workers/unity/
directory. Run it from the
<path_to_your_project/workers/unity
directory.$ sh fix-il2cpp-xcode.sh
- Download the script:
Run the project from Xcode by using the
Product->Run
menu, or usingCMD+R
, or pressing the play button.Note: As with all client workers, make sure that your server is running, either locally (
spatial local launch
) or from a deployment (spatial cloud launch
).
If successful, Xcode will complete the build and begin running the application on your iOS device or iOS Simulator.