将 Unity+Vuforia 集成到现有 iOS 项目使用户交互无法正常工作
Integrating Unity+Vuforia to existing iOS project make user interaction not working
目前我正在关注 this tutorial 将 Unity+Vuforia 项目集成到我现有的 iOS 项目中。我设法能够在我的 ARViewController 中显示 Unity 视图。问题是我在我的视图控制器中丢失了所有用户交互:我的后退按钮触摸事件没有启动。
import Foundation
class ARViewController: UIViewController {
var unityView: UIView?
static func instantiateViewController() -> ARViewController {
let controller = UIStoryboard.main.instantiateViewController(withIdentifier: "ARViewController") as! ARViewController
return controller
}
override func viewDidLoad() {
super.viewDidLoad()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.currentUnityController = UnityAppController()
appDelegate.currentUnityController?.application(UIApplication.shared, didFinishLaunchingWithOptions: nil)
appDelegate.startUnity()
NotificationCenter.default.addObserver(self, selector: #selector(handleUnityReady), name: NSNotification.Name("UnityReady"), object: nil)
}
}
@IBAction func onBackPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.stopUnity()
}
}
@objc func backPressedTest() {
}
@objc func handleUnityReady() {
showUnitySubView()
}
func showUnitySubView() {
guard let unityView = UnityGetGLView() else { return }
self.unityView = unityView
// insert subview at index 0 ensures unity view is behind current UI view
view?.addSubview(unityView)
unityView.translatesAutoresizingMaskIntoConstraints = false
let views = ["view": unityView]
let w = NSLayoutConstraint.constraints(withVisualFormat: "|-0-[view]-0-|", options: [], metrics: nil, views: views)
let h = NSLayoutConstraint.constraints(withVisualFormat: "V:|-50-[view]-0-|", options: [], metrics: nil, views: views)
view.addConstraints(w + h)
let button = UIButton(type: .custom)
button.setImage(#imageLiteral(resourceName: "ic_back_black").withRenderingMode(.alwaysTemplate), for: .normal)
button.addTarget(self, action:#selector(backPressed), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 28, height: 60)
button.widthAnchor.constraint(equalToConstant: button.frame.width).isActive = true
button.tintColor = UIColor.purpleBrown()
view?.addSubview(button)
}
}
我还注意到 Unity 的按钮在我触摸时也有任何效果。绿色条内的后退按钮来自 Unity。蓝色按钮来自我的 ARViewController。两者似乎都没有达到触摸事件。
调试要素:
当我将 Unity 配置放在 application:didFinishLaunchingWithOptions:
的顶部时,会发生这种情况,高于我在项目中使用的其他服务的现有配置。对于以后遇到这个问题的人,这是我的 appDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.application = application
// Another existing settings for the project, e.g. fabric
Fabric.with([Crashlytics.self])
// Put the Unity configuration at the bottom of the function
unity_init(CommandLine.argc, CommandLine.unsafeArgv)
currentUnityController = UnityAppController()
currentUnityController?.application(application, didFinishLaunchingWithOptions: launchOptions)
startUnity()
stopUnity()
return true
}
对于视图控制器中的viewWillAppear(_:)
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupBackBarButtonItems(back: true, isDark: true)
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.startUnity()
showUnitySubView()
}
}
正如@Prashant 在评论中提到的,UnityReady
通知只被调用一次。所以我不使用它。
然后我就在viewWillDisappear(_:)
中调用stopUnity()
:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.stopUnity()
}
}
现在的问题是离开屏幕无法杀掉unity进程。它是已知的 bug,如果可能的话,我仍在研究如何做到这一点。
我遇到了同样的问题,但将 Unity 配置移动到 applicationDidFinishLaunchingWithOption
方法的末尾并没有解决问题,我的屏幕前仍然有一个 UIWindow 窃取了所有用户交互。
我的解决办法不是在UnityAppController.mm
中新建window,而是使用当前的应用程序keyWindow。
替换:
_window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
与:
_window = [UIApplication sharedApplication].keyWindow;
目前我正在关注 this tutorial 将 Unity+Vuforia 项目集成到我现有的 iOS 项目中。我设法能够在我的 ARViewController 中显示 Unity 视图。问题是我在我的视图控制器中丢失了所有用户交互:我的后退按钮触摸事件没有启动。
import Foundation
class ARViewController: UIViewController {
var unityView: UIView?
static func instantiateViewController() -> ARViewController {
let controller = UIStoryboard.main.instantiateViewController(withIdentifier: "ARViewController") as! ARViewController
return controller
}
override func viewDidLoad() {
super.viewDidLoad()
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.currentUnityController = UnityAppController()
appDelegate.currentUnityController?.application(UIApplication.shared, didFinishLaunchingWithOptions: nil)
appDelegate.startUnity()
NotificationCenter.default.addObserver(self, selector: #selector(handleUnityReady), name: NSNotification.Name("UnityReady"), object: nil)
}
}
@IBAction func onBackPressed(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.stopUnity()
}
}
@objc func backPressedTest() {
}
@objc func handleUnityReady() {
showUnitySubView()
}
func showUnitySubView() {
guard let unityView = UnityGetGLView() else { return }
self.unityView = unityView
// insert subview at index 0 ensures unity view is behind current UI view
view?.addSubview(unityView)
unityView.translatesAutoresizingMaskIntoConstraints = false
let views = ["view": unityView]
let w = NSLayoutConstraint.constraints(withVisualFormat: "|-0-[view]-0-|", options: [], metrics: nil, views: views)
let h = NSLayoutConstraint.constraints(withVisualFormat: "V:|-50-[view]-0-|", options: [], metrics: nil, views: views)
view.addConstraints(w + h)
let button = UIButton(type: .custom)
button.setImage(#imageLiteral(resourceName: "ic_back_black").withRenderingMode(.alwaysTemplate), for: .normal)
button.addTarget(self, action:#selector(backPressed), for: .touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 28, height: 60)
button.widthAnchor.constraint(equalToConstant: button.frame.width).isActive = true
button.tintColor = UIColor.purpleBrown()
view?.addSubview(button)
}
}
我还注意到 Unity 的按钮在我触摸时也有任何效果。绿色条内的后退按钮来自 Unity。蓝色按钮来自我的 ARViewController。两者似乎都没有达到触摸事件。
调试要素:
当我将 Unity 配置放在 application:didFinishLaunchingWithOptions:
的顶部时,会发生这种情况,高于我在项目中使用的其他服务的现有配置。对于以后遇到这个问题的人,这是我的 appDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.application = application
// Another existing settings for the project, e.g. fabric
Fabric.with([Crashlytics.self])
// Put the Unity configuration at the bottom of the function
unity_init(CommandLine.argc, CommandLine.unsafeArgv)
currentUnityController = UnityAppController()
currentUnityController?.application(application, didFinishLaunchingWithOptions: launchOptions)
startUnity()
stopUnity()
return true
}
对于视图控制器中的viewWillAppear(_:)
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupBackBarButtonItems(back: true, isDark: true)
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.startUnity()
showUnitySubView()
}
}
正如@Prashant 在评论中提到的,UnityReady
通知只被调用一次。所以我不使用它。
然后我就在viewWillDisappear(_:)
中调用stopUnity()
:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.stopUnity()
}
}
现在的问题是离开屏幕无法杀掉unity进程。它是已知的 bug,如果可能的话,我仍在研究如何做到这一点。
我遇到了同样的问题,但将 Unity 配置移动到 applicationDidFinishLaunchingWithOption
方法的末尾并没有解决问题,我的屏幕前仍然有一个 UIWindow 窃取了所有用户交互。
我的解决办法不是在UnityAppController.mm
中新建window,而是使用当前的应用程序keyWindow。
替换:
_window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds];
与:
_window = [UIApplication sharedApplication].keyWindow;