Swift4下初步实现AR飞机的效果
1.先新建一个普通项目,删除掉Main.StoryBoard,以纯代码实现。先在Info.plist中设置相机的权限
相机权限
如果是新建AR项目,Info.plist中会自动建立该项权限。
2.新建一个控制器类,这里名为NormalPlaneViewController,
Import ARKit与SceneKit。
一个AR功能的实现,需要由ARSCNView来展示,由ARSession来执行ARSCNView与底层的交互,由ARConfiguration来追踪现实世界内的一些事物(方向,水平面,脸部等)。
<1>创建ARSession
lazy var arSession:ARSession = {
var lazyARSession = ARSession.init()
return lazyARSession
}()
<2>创建ARSCNView
lazy var arSCNView:ARSCNView = {
var lazyArSCNView = ARSCNView.init()
lazyArSCNView.frame = UIScreen.main.bounds
lazyArSCNView.session = self.arSession
return lazyArSCNView
}()
<3>创建ARConfiguration
在Apple的帮助文档中提到,ARConfiguration是一个抽象类,不提供具体的实现该类实例的方法,请实现它的子类。
ARConfiguration的子类包括有:
ARWorldTrackingConfiguration-可以提供平面检测、碰撞测试、可精确追踪后置摄像头的位置与方向来给用户提供高品质的AR体验。
AROrientationTrackingConfiguration-可以追踪设备的后置摄像头的方向来给用户提供基本的AR体验。
ARFaceTrackingConfiguration-可以使用设备的前置摄像头来追踪用户的脸部的移动和脸部表情来给用户提供AR体验。
我们这里选择使用ARWorldTrackingConfiguration来实现我们的AR。
lazy var arConfiguration:ARWorldTrackingConfiguration = {
var arWTConfiguration = ARWorldTrackingConfiguration.init()
//打开平面识别
arWTConfiguration.planeDetection = ARWorldTrackingConfiguration.PlaneDetection.horizontal
//使用灯光效果
arWTConfiguration.isLightEstimationEnabled = true
return arWTConfiguration
}()
3.创建材质包
由于是新建的一个简单项目,并非是AR项目,所以项目中不会自带.scnassets结尾的材质包,我们需要新建一个,方法也很简单。
首先New File,找到Asset Catalog,然后Next。
新建材质包
重命名一下,然后加上一个.scnassets的后缀,完成即可。
设置后缀
创建完成后文件名在目录中显示为Model.scnassets.xcassets,将多余的后缀删除。然后我们将我们的材质文件在Finder中拖入Model.scnassets文件夹中,再右键我们的Model.scnassets,Add File,将材质文件添加进来,重启Xcode就能在工程目录看到相应的文件了。
4.实现AR效果
这里实现一个静止的飞机出现在摄像头前的效果
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.view.addSubview(self.arSCNView)
self.arSession.run(self.arConfiguration, options: ARSession.RunOptions.resetTracking)
let scene = SCNScene.init(named: "Model.scnassets/ship.scn")
let shipNode = scene?.rootNode.childNodes[0]
self.arSCNView.scene.rootNode.addChildNode(shipNode!)
}
飞机效果
全部代码:
import UIKit
import ARKit
import SceneKit
class NormalPlaneViewController: UIViewController {
//MARK:懒加载AR控件等
lazy var arSCNView:ARSCNView = {
var lazyArSCNView = ARSCNView.init()
lazyArSCNView.frame = UIScreen.main.bounds
lazyArSCNView.session = self.arSession
return lazyArSCNView
}()
lazy var arSession:ARSession = {
var lazyARSession = ARSession.init()
return lazyARSession
}()
lazy var arConfiguration:ARWorldTrackingConfiguration = {
var arWTConfiguration = ARWorldTrackingConfiguration.init()
//打开平面识别
arWTConfiguration.planeDetection = ARWorldTrackingConfiguration.PlaneDetection.horizontal
arWTConfiguration.isLightEstimationEnabled = true
return arWTConfiguration
}()
//MARK:系统函数
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.view.addSubview(self.arSCNView)
self.arSession.run(self.arConfiguration, options: ARSession.RunOptions.resetTracking)
let scene = SCNScene.init(named: "Model.scnassets/ship.scn")
let shipNode = scene?.rootNode.childNodes[0]
self.arSCNView.scene.rootNode.addChildNode(shipNode!)
}
//MARK:自定义方法
}