【问题标题】:How to change the position of an object Swift SceneKit如何更改对象的位置 Swift SceneKit
【发布时间】:2019-02-14 05:38:15
【问题描述】:

我在一个 SceneKit 中有两个对象。一个是地球,另一个是月球。它们都位于 x:0、y:0、z:0 并重叠。我应该如何更改月球的坐标,使其绕地球运行?

代码如下:

import UIKit
import SceneKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let scene = SCNScene()

        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()

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

        scene.rootNode.addChildNode(cameraNode)

        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light?.type = .directional
        lightNode.position = SCNVector3(x:0, y:0, z:2)

        scene.rootNode.addChildNode(lightNode)

        let stars = SCNParticleSystem(named: "StarsParticles.scnp", inDirectory: nil)!
        scene.rootNode.addParticleSystem(stars)

        let moonNode = MoonNode()
        scene.rootNode.addChildNode(moonNode)

        let sceneview = self.view as! SCNView
        sceneview.scene = scene

        let earthNode = EarthNode()
        scene.rootNode.addChildNode(earthNode)

        let sceneView = self.view as! SCNView
        sceneView.scene = scene

        sceneView.showsStatistics = false
        sceneView.backgroundColor = UIColor.black
        sceneView.allowsCameraControl = true
    }

    override var prefersStatusBarHidden: Bool {
        return true 
    }
}

【问题讨论】:

    标签: ios swift scenekit


    【解决方案1】:

    您可以将您的视图控制器设为SCNSceneRendererDelegate,并实现委托方法renderer:willRenderScene,它会为您提供time。基于time,您可以设置如下内容:

    moonNode.position = SCNVector3(r * cos(Float(time), r * sin(Float(time)), 0)
    

    r 是地球节点的半径 - 如果您在编译时不知道这一点,只需在该行上方包含类似的内容:

    let r = length(float3(earthNode.boundingBox.max) - float3(earthNode.boundingBox.min))
    

    这对于我包含的导致 xy 平面旋转的代码来说并不完全准确,但它至少会为您提供r 的正确数量级。如果您收到无法找到 float3 或长度的错误,请尝试 import simd

    如果您对此有任何问题,请告诉我,因为我是从记忆中输入的。

    文档中的更多信息:https://developer.apple.com/documentation/scenekit/scnscenerendererdelegate/1523483-renderer

    【讨论】:

      【解决方案2】:

      您可以使用simdPivot 实例属性轻松完成。

      var simdPivot: simd_float4x4 { get set }
      

      这是一个测试代码:

      import SceneKit
      
      class GameViewController: UIViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
              let scene = SCNScene()
              let action = SCNAction.repeatForever(SCNAction.rotate(by: .pi, 
                                                                around: SCNVector3(0,1,0), 
                                                              duration: 1))
      
              let earthNode = SCNNode(geometry: SCNSphere(radius: 3.57))
              earthNode.geometry?.materials.first?.diffuse.contents = UIColor.blue
              scene.rootNode.addChildNode(earthNode)
      
              let moonNode = SCNNode(geometry: SCNSphere(radius: 0.15))
              moonNode.geometry?.materials.first?.diffuse.contents = UIColor.yellow
              moonNode.simdPivot.columns.3.x = 5
              moonNode.runAction(action)
              scene.rootNode.addChildNode(moonNode)
      
              let sceneView = self.view as! SCNView
              sceneView.scene = scene
      
              sceneView.backgroundColor = UIColor.black
              sceneView.allowsCameraControl = true
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2018-05-06
        • 1970-01-01
        • 2014-10-05
        • 1970-01-01
        • 2016-01-09
        • 1970-01-01
        • 2016-01-13
        • 1970-01-01
        • 2021-08-15
        相关资源
        最近更新 更多