我正在尝试使用ARKit,并使用this tutorial设置ARSCNView
。
然后使用this tutorial.
的第二部分设置跟踪水平3D平面我创建了一个单一的视图应用程序,然后将ARSCNView
刷新约束到根视图,其中包含我ViewController
的插座。
以下是ViewController
中的代码:
import UIKit
import ARKit
class ViewController: UIViewController {
//MARK: Properties
@IBOutlet weak var arScene: ARSCNView!
//MARK: ARKit variables
var realityConfiguration: ARWorldTrackingSessionConfiguration?
//MARK: Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.prepare()
}
//MARK: Actions
//MARK: Overrides
}
extension ViewController {
func prepare() {
//Check to see if active reality is supported
guard ARSessionConfiguration.isSupported else {
//Custom alert function that just quickly displays a UIAlertController
AppDelegate.alert(title: "Not Supported", message: "Active Reality is not supported on this device")
return
}
//Set up the ARSessionConfiguration
self.realityConfiguration = ARWorldTrackingSessionConfiguration()
//Set up the ARSCNView
guard let config = self.realityConfiguration else {
return
}
//Run the ARSCNView and set its delegate
self.arScene.session.run(config)
self.arScene.delegate = self
}
}
extension ViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
return nil
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let planAnchor = anchor as? ARPlaneAnchor else {
return
}
let plane = SCNPlane(width: CGFloat(planAnchor.extent.x), height: CGFloat(planAnchor.extent.z))
let planeNode = SCNNode(geometry: plane)
planeNode.position = SCNVector3Make(planAnchor.center.x, 0, planAnchor.center.z)
planeNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)
node.addChildNode(planeNode)
}
func renderer(_ renderer: SCNSceneRenderer, willUpdate node: SCNNode, for anchor: ARAnchor) {
print("Will updated Node on Anchor: \(anchor.identifier)")
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
print("Did updated Node on Anchor: \(anchor.identifier)")
}
func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {
print("Removed Node on Anchor: \(anchor.identifier)")
}
}
我下载了Xcode 9 beta,遵循了Apple的教程,并意识到我的iPhone 6没有ARWorldTrackingSessionConfiguration
对象所需的A9芯片。
在我链接的第一个教程中,大约有一半,Apple表示你仍然可以在没有A9芯片的情况下创建AR体验。但是,他们没有详细说明。是否有其他人找到了起点,并愿意提供使用.dae文件和
的代码示例答案 0 :(得分:30)
使用您的代码并没有什么可看的 - 只是一个实时的相机视图。
您在现实中没有看到任何增强的主要原因是,只有当锚点添加到ARSession
时,您的代码才会将SceneKit内容添加到场景中...但您不是手动添加任何锚点,并且您尚未启用平面检测,因此ARKit不会自动添加锚点。如果启用平面检测,您将开始到达某个地方......
self.realityConfiguration = ARWorldTrackingSessionConfiguration()
realityConfiguration?.planeDetection = .horizontal
但你仍然看不到任何东西。那是因为您的ARSCNViewDelegate
实施具有相互矛盾的说明。这部分:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
return nil
}
...表示不会为您的锚点创建SceneKit节点。因为没有节点,所以永远不会调用renderer(_:didAdd:for:)
函数,因此该方法中的代码永远不会创建任何SceneKit内容。
如果您打开平面检测并删除/注释掉renderer(_: nodeFor:)
方法,则代码的其余部分应该为您提供以下内容:
(纯白色区域是你的SCNPlane
。我必须在白色桌子上展开我的iPad封面,获得足够的场景细节,以便找到任何平面。另外,检查背景......实际上有一个在今天的WWDC上,那里的商店里面没有满满的人。)
至于你是否需要A9,Apple的消息在这里有点不清楚。当他们说ARKit需要A9或更好时,他们真正的意思是ARWorldTrackingSessionConfiguration。这就是所有最好的AR魔术所在。 (UIRequiredDeviceCapabilities
的{{1}}键实际上涵盖了具有全球跟踪支持功能的设备,因此您可以将App Store上的应用限制为只提供给这些设备。)
但是仍然有某些 ARKit没有世界跟踪。使用基类ARSessionConfiguration
运行会话,您将获得仅定向跟踪。 (没有位置跟踪,没有平面检测,没有命中测试。)
这对你有什么影响?好吧,如果你玩过当前版本的PokémonGO,那就是这样的:因为它只跟踪设备方向,而不是位置,你无法靠近皮卡丘或在他身后走来走去 - 他占据真实的错觉只要您在不移动设备的情况下倾斜或转动设备,世界就会保持。
您使用SceneKit加载3D内容并将其放入AR,就像您加载并将其放置在任何其他SceneKit应用程序/游戏中一样。这里有很多资源,有很多方法可以做到这一点。当您创建一个新的AR项目并选择SceneKit时,您将在Xcode模板中找到其中一个。装载部分是这样的:
arkit
然后放置它:
let scene = SCNScene(named: "ship.scn" inDirectory: "assets.scnassets")
let ship = scene.rootNode.childNode(withName: "ship", recursively: true)
在AR中放置物品需要记住的主要区别是,位置以米为单位进行测量(您的内容需要设计为以米为单位进行合理调整)。