Using Unity with Swift for AR
In this post, I’ll dive into some of the technical challenges of AR as well as our preferred solution, focusing on integrating Unity into an iOS project.
Since the introduction of ARKit with iOS 11, we've seen an increasing demand for applications incorporating some form of Augmented Reality (AR) experience. AR is a relatively new technology that enhances the user's real world with virtual audio/visual objects, and a mobile phone or tablet is a perfect platform for this tech.
In this post, I’ll dive into some of the technical challenges of AR as well as our preferred solution, focusing on integrating Unity into an iOS project.
The first technical requirement for a compelling AR experience is an understanding of where the user is in space.
Apple's ARKit and Google's ARCore offer positional tracking and spatial mapping to construct a 3D representation of the user's environment, using just the camera and sensors built into the phone. These technologies are fairly similar in that they provide a context for how to render augmented content in a way that looks convincing; for example, a 3D rendered coffee mug at the correct position and perspective so that it appears to rest on a physical table.
Apple offers SceneKit as a rendering solution that closely integrates with ARKit, but I've found it very cumbersome to use, and of course, it's iOS only. Unity is a simpler and more powerful cross-platform alternative, and is one of the most prominent 3rd party rendering engines for mobile applications.
One of the primary reasons for its popularity is the extensive developer community, and therefore accessibility of learning content. It's incredibly easy to get started building a convincing 3D scene, and then deploy it to both iOS and Android.
Unfortunately, it's difficult to integrate that scene into an existing Xcode project due to the Unity build process, which generates an Xcode project that expects to control the entire app.
There are several advantages, however, to embedding Unity in an existing project. Primarily, almost all new projects these days use Swift, but the generated Unity project is written in Objective-C++. Additionally, 3D or AR experiences are often just a single feature in a much larger app, meaning it would be convenient to treat Unity as any other screen to be presented modally or in a navigation controller. There's no official support for including Unity in another app in this manner, but that doesn't mean it's impossible!
We've put together a template for a Swift project that embeds a Unity project as a single view controller.
You can download the template, which includes instructions for starting or configuring your own projects here. This repository provides Xcode build configs and Unity pre- and post-build scripts that keep the two projects in sync automatically. Simply building the Unity project will build for iOS device and simulator, and link those build products in the Swift project. From there, the native Swift code can present or dismiss the Unity scene just like any other view controller.
The included sample project also shows how to integrate with Vuforia, a powerful, cross-platform AR platform with advanced features such as object recognition and some of the most accurate model placement available. It uses ARKit or ARCore under the hood, depending on the platform, and is also built into Unity, allowing developers to enable it with a single checkbox.
The use cases of Unity integration into a larger Swift project certainly aren't limited to AR. Unity’s cross-platform support (which is especially helpful for Android… but more on that in a later post!) and unique features such as the ability to seamlessly integrate UI into both 2D and 3D space (a challenging task in native iOS because UIKit can't render into SceneKit contexts) make it an extremely powerful tool. In addition, anything requiring 3D rendering, physics simulation, or even complex audio or video features is often easier to implement in Unity than in the corresponding native frameworks.
Have fun!
You can find the repo, along with detailed integration instructions, here: https://github.com/rocketinsights/Unity-iOS