如何更改Swift SceneKit对象的位置

问题描述 投票:1回答:2

我在一个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
2个回答
0
投票

你可以让你的视图控制器成为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或length的错误,请尝试和import simd

如果您对此有任何疑问,请告诉我,因为我是从内存中输入的。

更多信息,请参阅文档:https://developer.apple.com/documentation/scenekit/scnscenerendererdelegate/1523483-renderer


0
投票

您可以使用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
    }
}

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.