sceneKit-clone很有用

本节任务

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

Swift原型

clone() -> Self

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

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

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

我们举一个简单的例子

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

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

然后我们加载文件模型

  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

运行结果如上

第二种 方式

let boss = scene.rootNode.childNode(withName: "bossGroup", recursively: true)
boss?.position = SCNVector3(x: 0, y: 0, z: -1000)

运行结果如上

第三种 方式

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.首先创建一个空的场景

    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.将模型文件中的模型加载到场景中去

    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方法

        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文件的包含多个模型,你需要一次性将他们全部加入场景中,你可能会像下面一样

    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 之后,遇到这个程序直接崩溃,所以我们遇到这种情况需要像下面这样做

    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())

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SceneKit- 画中画效果实现方案

    白的部分是一个plane几何的节点,我们需要将一个SCNScene渲染到这个节点上,来实现画中画效果

    酷走天涯
  • Foundation-Array

    酷走天涯
  • SceneKit - 提供两种最常用的将序列帧动画渲染到模型上的方式

    这个时候,你运行程序是没有动画效果的,因为模型是静止的,scenekit 不会对静止的模型实时渲染,这个时候要让模型渲染imageview 有两种办法,第一种就...

    酷走天涯
  • 找实习中的一些困惑,如何解决?

    对于大三/研二的来说,已经到了春招找暑期实习备战阶段了(最迟学校期末考完试),这个时间点是最合适的,实习怎么找?可以先看一下我之前写的一篇:

    乔戈里
  • Dynamic Web Module 3.0 requires Java 1.6 or newer.的解决

    ydymz
  • 2017前端开发手册四-前端开发人员应该掌握的Web技术

    碰见过真正难相处的人,才知道身边的伙伴们多么值得珍惜。 ? 前端开发人员应掌握以下核心网络技术(考虑按此顺序学习): 统一资源定位器(又名URL) 超文本传输协...

    司想君
  • 实际开发中的深浅拷贝问题 - 解答

    小蠢驴打代码
  • 「学习笔记」循环、列表

    continue:终止本轮循环并开始下一轮循环(开始下一轮之前会先看循环条件是否满足,满足了才执行)

    用户2398817
  • 《Python 源码剖析》一些理解以及勘误笔记(3)

    以下是本人阅读此书时理解的一些笔记,包含一些影响文义的笔误修正,当然不一定正确,贴出来一起讨论。 注:此书剖析的源码是2.5版本,在python.org 可...

    s1mba
  • js --- 事件冒泡 事件捕获

      他们是描述事件触发时序问题的术语。事件捕获指的是从document到触发事件的那个节点,即自上而下的去触发事件。相反的,事件冒泡是自下而上的去触发事件。绑定...

    小蔚

扫码关注云+社区

领取腾讯云代金券