目前网上关于SceneKit的教程还是略少。对于完全没有任何游戏开发经验的人(我)来说还是有一定挑战。记下此篇,加深理解。文中不保证完全正确,如有错误,感谢斧正。
本文不会像教材一样循规蹈矩,按部就班。而是通过实例,用到了什么再去学习什么。
进入正题:
Hello World
1、创建工程
很多没基础的人(我)都栽在了第一步。Xcode->File->New->Project->Game->SceneKit->Run!
看到一个很炫酷的飞船,在原地不停转圈。一看代码,不明觉厉。于是就放弃了。
其实SceneKit没有那么神秘,他就是一个framework,我们完全可以使用他,就像使用任意一个framework一样。
所以在这里,我们新建一个Single View App就可以了。
接下来,如所有开发一样,来开发一个
HelloWorld
作为学习的开头吧。
2、引入SceneKit
如前文所说,就像我们使用任意一个framework,我们首先引入它。
#import <SceneKit/SceneKit.h>
到这,我们先想一个概念:SceneKit
开发的东西,自然应该放在SceneKit
自己的容器上,SCNView
就是这个容器(记不住前缀的可以脑补英文发音s ~ c ~ n:scene)。它提供一个场景SCNScene
,而我们具体的每一个组件都将放在场景里,这些组件便是节点SCNNode
。
于是我设定了以下3步来完成HelloWorld
。
- (void)viewDidLoad {
[super viewDidLoad];
[self makeScene];//1、初始化场景
[self makeNode]; //2、初始化节点
[self rotation]; //3、旋转节点
}
3、初始化场景
查看API可以看到SCNView
其实就是一个基于UIView
的控件,我们可以像初始化UIView
一样初始化它。
#pragma mark - 初始化Scene
-(void)makeScene {
_scnView = [[SCNView alloc]initWithFrame:CGRectMake(0, 0, 300, 300)];
[self.view addSubview:_scnView];
_scnView.center = self.view.center;
[_scnView setBackgroundColor:[UIColor lightGrayColor]];
//设置场景
SCNScene *scene = [SCNScene new];
_scnView.scene = scene;
}
初始化SCNView
之后必须做的是给它设置一个场景,SCNScene
可以像上文中一样使用+(instancetype)new;
或者+(instancetype)scene;
初始化一个空场景。也可以根据资源创建场景+(instancetype)sceneNamed:(NSString *)name;
这个资源可以是.scn文件也可以是.dae文件。(然而我并不知道去哪找现成的资源,所以接下来的实例,都只能以图形加颜色为主)
.scn文件可以->New->File->SceneKit Scene File创建
4、初始化节点
什么是节点?
A structural element of a scene graph, representing a position and transform in a 3D coordinate space, to which you can attach geometry, lights, cameras, or other displayable content.
场景里的元素,表示在三维坐标空间中的一个位置和变换,你可以将几何、灯光、相机或其他可显示的内容附加到其中。
就是说,节点本身不是东西,他只是代表一个位置和变换。我们可以把具体的组件附加到节点上,从而使组件显示出来。
#pragma mark - 初始化Node
-(void)makeNode {
//创建节点
_node = [SCNNode new];
//将节点附加到根节点上
[_scnView.scene.rootNode addChildNode:_node];
//设置节点形状
SCNText *text = [SCNText textWithString:@"Hello World" extrusionDepth:0.5];//extrusionDepth厚度
text.font = [UIFont systemFontOfSize:1];
_node.geometry = text;
//初始化光线(不是在目标上直接设置而是新建节点来作为光源)
SCNNode *lightNode = [SCNNode node];
lightNode.light = [SCNLight light];
lightNode.light.type = SCNLightTypeOmni;
lightNode.position = SCNVector3Make(0, 10, 10);
[_scnView.scene.rootNode addChildNode:lightNode];
SCNNode *ambientLightNode = [SCNNode node];
ambientLightNode.light = [SCNLight light];
ambientLightNode.light.type = SCNLightTypeAmbient;
ambientLightNode.light.color = [UIColor darkGrayColor];
[_scnView.scene.rootNode addChildNode:ambientLightNode];
//初始化虚拟相机(主要是调整镜头)
SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = [SCNCamera camera];
[_scnView.scene.rootNode addChildNode:cameraNode];
_scnView.allowsCameraControl = YES;
cameraNode.position = SCNVector3Make(0, 1, 12);
}
首先初始化node,并且把它添加到场景里。
接下来把“Hello World”附加给他,这样我们想要的文字就会出现在node的位置,并跟着node的变化而变化。
在这里我们想要显示文字、显示图形都是通过设置node的几何形状node.geometry
完成的。
接下来练手顺便创建了光线和相机。这里要注意,光源并不是想我们(我)想象的那样,直接设置给node,而是,新建额外的node作为光源,实际物件上的光是光源映射在物件上的效果。
虚拟相机可以调整镜头,从而调整物件显示的位置,大小等。还可以通过设置
_scnView.allowsCameraControl = YES;
对场景进行一些操作。这里先不深究。
5、旋转
其实就是SCNNode
的变换。可以通过CABasicAnimation
- (void)addAnimation:(id <SCNAnimation>)animation forKey:(NSString *)key;
或者SCNAction
- (void)runAction:(SCNAction *)action;
等来实现。
恰好两种都不熟悉,于是从简单的学起吧。
#pragma mark - 旋转
-(void)rotation {
SCNAction *customAction = [SCNAction rotateByX:0 y:1 z:0 duration:1];//沿y轴旋转
SCNAction *repeatAction = [SCNAction repeatActionForever:customAction];
[_node runAction:repeatAction];
}
创建一个沿y轴旋转的操作,并让它永远重复。
以上,完成了我们的第一个SceneKit程序。
说得有些啰嗦,实际上Demo代码一共只有几十行。主要是第一篇,所有知识点都是新概念。实际上还有一些知识点并不详细,将在之后陆续完善。