How to run unity game from iOS app
Setup
- Create unity project with any custom settings
- If running in iOS simulator
- change the
Target SDK
under player settings toSimulator SDK
- change the
- Create build for iOS
- Create a new swift UI app from xcode
- Run it to check if it works fine without any errors
- Create a new workspace from xcode
- Open workspace
- Right click on the left project navigation panel and click
add files to <workspace-name>
- Choose
Unity-iPhone.xcodeproj
from the unity build folder which we created earlier and selectcreate groups for any added folders
- Choose
<swift-ui-app>.xcodeproj
from the swift UI app folder which we created earlier and selectcreate groups for any added folders
- Now, we have both unity build and iOS app together in the xcode workspace
Integrate unity app with swift UI
Add
UnityFramework.framework
in iOS app target. It is underTargets > General > Frameworks, Libraries, and Embedded Content
aAdd
Data
folder to UnityFramwork. SelectData
folder under the Unity project and on the right side panel, check theUnityFramework
checkbox underTarget Membership
Add a new swift class to iOS project
- Paste this below code inside that file
swiftimport Foundation import UnityFramework class Unity: UIResponder, UIApplicationDelegate { static let shared = Unity() private let dataBundleId: String = "com.unity3d.framework" private let frameworkPath: String = "/Frameworks/UnityFramework.framework" private var ufw : UnityFramework? private var hostMainWindow : UIWindow? private var isInitialized: Bool { ufw?.appController() != nil } func show() { if isInitialized { showWindow() } else { initWindow() } } func setHostMainWindow(_ hostMainWindow: UIWindow?) { self.hostMainWindow = hostMainWindow } private func initWindow() { if isInitialized { showWindow() return } guard let ufw = loadUnityFramework() else { print("ERROR: Not able to load Unity") return unloadWindow() } self.ufw = ufw ufw.setDataBundleId(dataBundleId) ufw.register(self) ufw.runEmbedded( withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: nil ) } private func showWindow() { if isInitialized { ufw?.showUnityWindow() } } private func unloadWindow() { if isInitialized { ufw?.unloadApplication() } } private func loadUnityFramework() -> UnityFramework? { let bundlePath: String = Bundle.main.bundlePath + frameworkPath let bundle = Bundle(path: bundlePath) if bundle?.isLoaded == false { bundle?.load() } let ufw = bundle?.principalClass?.getInstance() if ufw?.appController() == nil { let machineHeader = UnsafeMutablePointer<MachHeader>.allocate(capacity: 1) machineHeader.pointee = _mh_execute_header ufw?.setExecuteHeader(machineHeader) } return ufw } } extension Unity: UnityFrameworkListener { func unityDidUnload(_ notification: Notification!) { ufw?.unregisterFrameworkListener(self) ufw = nil hostMainWindow?.makeKeyAndVisible() } }
- Replace
ContentView.swift
file with this below code
swiftimport SwiftUI struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") Button(action: { Unity.shared.show() }) { Text("Launch Unity") } } .padding() } } #Preview { ContentView() }
Run the iOS target, that's all.
Unity game should launch now by clicking the
Launch Unity
text in the iOS app.