iOS开发之SceneKit框架--实战地月系统围绕太阳旋转
1、创建地月太阳系统scn文件
注意:moon在earth结构下,earth和moon在sun结构下。
2、获取scn中模型的对应节点和自转(太阳为例)
- 获取节点: name是对应的Identity字符串
self.sunNode = [scene.rootNode childNodeWithName:@"sun" recursively:YES];
- 自转:围绕Y轴旋转
[self.sunNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]];
3、地月系统的公转和月亮公转
- 月亮公转是围绕地球的中心转,但是旋转动画只会围绕自身的轴旋转,所以将moonNode添加到earthNode,这样月球的公转和地球自转一样;
- 但是月亮公转不和地球自转一致,所以需要新建node节点,位置和地球node一样,将moomNode添加到新建的node上,新建node添加到地球node;
//新建月球公转node和设置旋转 self.moonRotationNode = [SCNNode node]; self.moonRotationNode.position = self.sunNode.position; [self.moonRotationNode addChildNode: self.moonNode]; [self.earthNode addChildNode:self.moonRotationNode]; [self.moonRotationNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:3 z:0 duration:1]]];
- 同样地月系统也新建node与太阳node位置相同,添加到太阳node上
//新建地月系统和设置旋转 self.earthGroupNode = [SCNNode node]; self.earthGroupNode.position = self.sunNode.position; [self.earthGroupNode addChildNode:self.earthNode]; [self.earthGroupNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]]; [self.sunNode addChildNode:self.earthGroupNode];
4、父子node的关系
- 每个node节点都拥有一个以自身为原点的坐标系
注意:之前提到需要注意结构层次 正确的层次moon在earth下
错误的层次 moon在sun下
- 这个模型的节点树
说明:moonNode应该在earthNode下,此时位置为(2,0,0)。如果是错误层次位置就是(12,0,0)。效果就像上面一样。
- 对父node添加的动画也会作用于所有的子node
说明:地球围绕太阳公转,但没有设置月球围绕太阳转的动画?
但是月球在地球的层次下,地月系统都是太阳的子node,所有动画就作用于月球上。
5、相关代码
- (void)viewDidLoad { [super viewDidLoad]; SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/sun.scn"]; SCNNode *cameraNode = [SCNNode node]; cameraNode.camera = [SCNCamera camera]; [scene.rootNode addChildNode:cameraNode]; cameraNode.position = SCNVector3Make(0, 0, 45); self.sCNView= (SCNView *)self.view; self.sCNView.scene = scene; self.sCNView.allowsCameraControl = YES; self.sCNView.showsStatistics = YES; self.sCNView.autoenablesDefaultLighting = YES; self.sunNode = [scene.rootNode childNodeWithName:@"sun" recursively:YES]; [self.sunNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]]; [self.sCNView.scene.rootNode addChildNode:self.sunNode]; self.lightNode = [scene.rootNode childNodeWithName:@"sunOmni" recursively:YES]; self.earthNode = [scene.rootNode childNodeWithName:@"earth" recursively:YES]; [self.earthNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:2 z:0 duration:1]]]; //新建地月系统和设置旋转 self.earthGroupNode = [SCNNode node]; self.earthGroupNode.position = self.sunNode.position; [self.earthGroupNode addChildNode:self.earthNode]; [self.earthGroupNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:1 z:0 duration:1]]]; [self.sunNode addChildNode:self.earthGroupNode]; //获取月球node和设置自转 self.moonNode = [scene.rootNode childNodeWithName:@"moon" recursively:YES]; [self.moonNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:4 z:0 duration:1]]]; //新建月球公转node和设置旋转 self.moonRotationNode = [SCNNode node]; self.moonRotationNode.position = self.sunNode.position; [self.moonRotationNode addChildNode: self.moonNode]; [self.earthNode addChildNode:self.moonRotationNode]; [self.moonRotationNode runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:3 z:0 duration:1]]]; }
ForeverGuard博客园