一、与SceneKit的对比
和SceneKit项目结构图一样,SpriteKit项目中多了一个Scene.sks的文件,这个文件是SpriteKit的场景文件,该文件只能看到2D平面。
二、效果
- 运行时,看到界面上只有相机画面。此时点击屏幕,就会出现一棵小松树,每多点一次,就会多一棵小松树。
- 不管你怎么移动手机,小松树始终朝向你,当你有多棵小松树时,它们之间始终保持一定的距离。
- SpriteKit会把2D图像以漂浮的方式放入3D空间中,就类似一个广告牌放置在某处,当你移动设备时,这个广告牌始终朝向你。
三、创建AR项目
- Content Technology:SpriteKit渲染框架
- 代码解析:
#import "ViewController.h"
#import "Scene.h"
@interface ViewController () <ARSKViewDelegate>
@property (nonatomic, strong) IBOutlet ARSKView *sceneView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Set the view's delegate
//设置视图代理
self.sceneView.delegate = self;
// Show statistics such as fps and node count
//显示FPS信息
self.sceneView.showsFPS = YES;
//显示节点数
self.sceneView.showsNodeCount = YES;
// Load the SKScene from 'Scene.sks'
//加载资源文件
Scene *scene = (Scene *)[SKScene nodeWithFileNamed:@"Scene"];
// Present the scene
//在视图中替换掉当前的场景,并且显示刚才加载的场景
[self.sceneView presentScene:scene];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Create a session configuration
//创建会话配置对象
ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
// Run the view's session
//运行当前视图自带的会话
[self.sceneView.session runWithConfiguration:configuration];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// Pause the view's session
//停止运行当前视图自带的会话
[self.sceneView.session pause];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - ARSKViewDelegate
- (SKNode *)view:(ARSKView *)view nodeForAnchor:(ARAnchor *)anchor {
// Create and configure a node for the anchor added to the view's session.
//创建并设置一个节点,并且把它放到会话给定的锚点(位置)上
SKLabelNode *labelNode = [SKLabelNode labelNodeWithText:@"👾"];
labelNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
labelNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
return labelNode;
}
#import "Scene.h"
@implementation Scene
- (void)didMoveToView:(SKView *)view {
// Setup your scene here
}
- (void)update:(CFTimeInterval)currentTime {
// Called before each frame is rendered
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (![self.view isKindOfClass:[ARSKView class]]) {
return;
}
ARSKView *sceneView = (ARSKView *)self.view;
ARFrame *currentFrame = [sceneView.session currentFrame];
// Create anchor using the camera's current position
//使用摄像头当前的位置创建一个锚点
if (currentFrame) {
// Create a transform with a translation of 0.2 meters in front of the camera
//创建一个向摄像头前方平移0.2m的转换
matrix_float4x4 translation = matrix_identity_float4x4;
translation.columns[3].z = -0.2;
//使用当前帧中摄像头的位置进行转换,转换后得到一个矩阵
matrix_float4x4 transform = matrix_multiply(currentFrame.camera.transform, translation);
// Add a new anchor to the session
//新建一个锚点并添加到会话中
ARAnchor *anchor = [[ARAnchor alloc] initWithTransform:transform];
[sceneView.session addAnchor:anchor];
}
}