如何在屏幕中央添加一个立方体,使其永远不会离开?

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

下午好!我是SceneKit的新手。我不能解决这个问题。

我需要让立方体一直位于屏幕中央,并跟随相机,直到找到水平并站立在其上。我把它留在一个地方这是我现在的简单代码。

        import UIKit
        import SceneKit
        import ARKit

        class ViewController: UIViewController, ARSCNViewDelegate {

            @IBOutlet var sceneView: ARSCNView!

            override func viewDidLoad() {
                super.viewDidLoad()


                let scene = SCNScene()


                let boxGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)


                let material = SCNMaterial()

                material.diffuse.contents = UIColor.blue
                material.specular.contents = UIColor(white: 0.6, alpha: 1.0)



                let boxNode = SCNNode(geometry: boxGeometry)
                boxNode.geometry?.materials = [material]


                boxNode.position = SCNVector3(0,0,-1.0)


                scene.rootNode.addChildNode(boxNode)

                sceneView.scene = scene


                //------------------------------------
                // Set the view's delegate
                sceneView.delegate = self

                // Show statistics such as fps and timing information
                sceneView.showsStatistics = true


                // Set the scene to the view
                sceneView.scene = scene
            }

            override func viewWillAppear(_ animated: Bool) {
                super.viewWillAppear(animated)

                // Create a session configuration
                let configuration = ARWorldTrackingConfiguration()

                // Run the view's session
                sceneView.session.run(configuration)
            }

            override func viewWillDisappear(_ animated: Bool) {
                super.viewWillDisappear(animated)

                // Pause the view's session
                sceneView.session.pause()
            }

       }

请帮帮我。不发誓)

swift xcode scenekit arkit
1个回答
0
投票

这里是对您代码的更新,以确保该框始终位于屏幕中央。一旦代码检测到平面,它将框的父级设置为平面锚点。

这都是非常原始的,但是应该可以帮助您。如果要使节点浮动在屏幕中央,请取消注释SCNTransaction回调中的willRenderScene。如果希望框始终面对用户,则可以添加lookAtConstraint

import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!
    var boxNode: SCNNode? // keep a reference to the cube

    override func viewDidLoad() {
        super.viewDidLoad()


        let scene = SCNScene()


        let boxNode = createBox()
        scene.rootNode.addChildNode(boxNode)
        self.boxNode = boxNode

        sceneView.scene = scene


        //------------------------------------
        // Set the view's delegate
        sceneView.delegate = self

        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true


        // Set the scene to the view
        sceneView.scene = scene
    }

    func createBox() -> SCNNode {
        let boxGeometry = SCNBox(width: 0.2, height: 0.2, length: 0.2, chamferRadius: 0)

        let material = SCNMaterial()
        material.diffuse.contents = UIColor.blue
        material.specular.contents = UIColor(white: 0.6, alpha: 1.0)

        let boxNode = SCNNode(geometry: boxGeometry)
        boxNode.geometry?.materials = [material]

        return boxNode;
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = .horizontal

        // Run the view's session
        sceneView.session.run(configuration)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
    }

    // on willRender update the cube's position.
    func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
        // get camera translation and rotation
        guard let pointOfView = sceneView.pointOfView else { return }
        let transform = pointOfView.transform // transformation matrix
        let orientation = SCNVector3(-transform.m31, -transform.m32, -transform.m33) // camera rotation
        let location = SCNVector3(transform.m41, transform.m42, transform.m43) // camera translation

        let currentPostionOfCamera = orientation + location
//        SCNTransaction.begin()
        if let boxNode = self.boxNode {
            boxNode.position = currentPostionOfCamera
        }
//        SCNTransaction.commit()
    }


    // detect plances
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        guard anchor is ARPlaneAnchor else { return }
        if let boxNode = self.boxNode {
            let newBoxNode = createBox() // create a new node for the center of the screen
            self.boxNode = newBoxNode
            SCNTransaction.begin()
            boxNode.removeFromParentNode()
            node.addChildNode(boxNode) // set the current box to the plane.
            sceneView.scene.rootNode.addChildNode(newBoxNode) // add the new box node to the scene
            SCNTransaction.commit()
        }

    }
}

extension SCNVector3 {
    static func + (left: SCNVector3, right: SCNVector3) -> SCNVector3 {
        return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.