前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >sceneKit-clone很有用

sceneKit-clone很有用

作者头像
酷走天涯
发布2019-06-15 11:20:30
1.2K1
发布2019-06-15 11:20:30
举报

本节任务

SCNNode的clone方法你要知道怎么用?

Swift原型

代码语言:javascript
复制
clone() -> Self

从这个方法的名字我们知道它就是在克隆对象,什么是克隆?就是复制一个一模一样的东西出来,计算机中的克隆,其实是创建一个新的内存空间,将一对象占用的内存数据全部复制一份到另一个内存空间里

下面讲解一下SCNNode的clone方法都干了什么事情?

1.克隆的节点是自动管理内存的 2.克隆节点的时候,子节点也会被克隆 3.源节点和克隆的节点共享的对象有light, geometry, camera等 4.如果你想要独立的改变副本的某些共享对象,就必须分别复制节点的共享对象,或者为它创新创建这些对象

我们举一个简单的例子

13E81C3A-9D16-4446-A158-725530B31084.png

这里有一个模型文件包含了骨骼动画,先把它导入到工程中去(记得使用右击导入文件的方式)

然后我们加载文件模型

代码语言:javascript
复制
  let url =  Bundle.main.url(forResource: "boss", withExtension: "dae")
  let scene = try! SCNScene(url: url!, options: nil)

   let scene = SCNScene()
    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(cameraNode)
    cameraNode.camera?.automaticallyAdjustsZRange = true
    let scnView = self.view as! SCNView
    scnView.scene = scene

B81357FE-B760-4CD2-A4A2-5D1F85CB14A5.png

我们注意到模型的大小为 width:348.292 height:649 depth:368.192

此时运行发现 什么都看不到,原因很简单,是由于我们的模型太大了

有三种方法可以让我看的到模型

1.将相机沿着+z轴的方向移动 2.将模型沿着-z轴的方向移动 3.改变模型的比例值

第一种 方式

cameraNode.position = SCNVector3(x: 0, y: 0, z: 1000)

64A1F7E1-C726-404D-AAAF-15EB1DF275D1.png

运行结果如上

第二种 方式

代码语言:javascript
复制
let boss = scene.rootNode.childNode(withName: "bossGroup", recursively: true)
boss?.position = SCNVector3(x: 0, y: 0, z: -1000)

运行结果如上

第三种 方式

代码语言:javascript
复制
let boss = scene.rootNode.childNode(withName: "bossGroup", recursively: true)
 boss?.scale = SCNVector3Make(0.01, 0.01, 0.01)

DC0CF5A4-BEB3-463E-A323-A22D90D0BCDF.png

发现是可以的

如果我们要将多个模型加载到一个场景下应该怎么办呢?

接下来,我们来演示一下过程

1.首先创建一个空的场景

代码语言:javascript
复制
    let scene = SCNScene()
    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(cameraNode)
    cameraNode.camera?.automaticallyAdjustsZRange = true
    // place the camera
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 0)
    let scnView = self.view as! SCNView
    scnView.scene = scene

2.将模型文件中的模型加载到场景中去

代码语言:javascript
复制
    let url =  Bundle.main.url(forResource: "boss", withExtension: "dae")
    let bossScene = try! SCNScene(url: url!, options: nil)
    let boss = bossScene.rootNode.childNode(withName: "bossGroup", recursively: true)
    boss?.position = SCNVector3Make(0, 0, -3000)
    scene.rootNode.addChildNode(boss!)

运行结果如下

9BF48E75-5EA6-4891-89BD-7288FF67591D.png

这个时候,我们想要创建很多个怪兽,最优化的办法就是使用clone方法

代码语言:javascript
复制
        for i in 0...20 {
        var bossCopy = boss?.clone()
        bossCopy!.position = SCNVector3Make(0, Float(i * 100), -3000)
        scene.rootNode.addChildNode(bossCopy!)
    }

86060B8B-B220-45AC-AAE5-4A66904483B1.png

有时候你会发现 你直接加载的场景文件中的模型 不能调节位置属性,这个时候你只需要clone一下模型 然后在添加到场景的rootNode 节点上即可

下面还有一种情况 必须使用clone

如果你想要将boss.dea文件的包含多个模型,你需要一次性将他们全部加入场景中,你可能会像下面一样

代码语言:javascript
复制
    let url =  Bundle.main.url(forResource: "boss", withExtension: "dae")
    let bossScene = try! SCNScene(url: url!, options: nil)
    let boss = bossScene.rootNode
    boss.position = SCNVector3Make(0, 0, -3000)
    scene.rootNode.addChildNode(boss)

这个时候会报一个错误

Error: removing the root node of a scene from its scene is not allowed

iOS 11 之后,遇到这个程序直接崩溃,所以我们遇到这种情况需要像下面这样做

代码语言:javascript
复制
    let url =  Bundle.main.url(forResource: "boss", withExtension: "dae")
    let bossScene = try! SCNScene(url: url!, options: nil)
    let boss = bossScene.rootNode
    boss.position = SCNVector3Make(0, 0, -3000)
    scene.rootNode.addChildNode(boss.clone())
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.09.19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档