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 条评论
登录 后参与评论

相关文章

  • iOS - SceneKit显示与交互3D建模(一)

    LinXunFeng
  • 第一节 介绍

    Step 1 打开Xcode -> 新建一个工程-> 选择SingleView Application -> Next -> 你已经完成工程的创建

    酷走天涯
  • VR+全景播放器+头控讲解-01

    近两年随着AR/VR逐渐火热,企业为了给自己的产品中加入新的元素,有可能会将3D元素添加到应用中去,对于IOS 工程师,你有三种选择 OpenGL ES / M...

    酷走天涯
  • 100 行代码写一个手机AR

    Step-1.实现两个协议 1.AVCaptureMetadataOutputObjectsDelegate 2.UINavigationControlle...

    酷走天涯
  • iOS版 使用ARKit和Swift创建交互式Domino游戏

    在下面的教程中,我将向您展示如何使用Swift和ARKit制作有趣的Domino游戏。

    iOSDevLog
  • ARKit by Example - 第1部分:AR立方体

    这篇第一篇文章将使用ARKit创建一个非常简单的hello world AR应用程序。最后,我们将能够在增强的世界中定位3D立方体,并使用我们的iOS设备移动它...

    iOSDevLog
  • ARKit浅析V1.0

    一、ARKit介绍 苹果公司在WWDC2017 上发布了ARKit,开发者可以使用这套框架在iPhone和iPad上创建属于自己的AR体验。 增强现实技术(A...

    MelonTeam
  • IOS开发必须知道的3DLabel实现过程

    最近写了很多关于SceneKit 的入门教程文章,初衷就是想给应用增加一点色彩,今天就教大家实现一个简单的3DLabel 的小框架.如果你的应用中需要实现3D字...

    酷走天涯
  • ARKit中控制.dae动画的播放

    4.用时间控制动画--CAAnimation 里的 timeOffset 控制开始时间 duration控制播放时间

扫码关注云+社区

领取腾讯云代金券