只能移动放置在Scene中的最后一个对象

时间:2018-04-12 13:55:44

标签: scenekit arkit

HY!我只能移动放置在场景中的最后一个虚拟对象。当我添加另一个对象时,添加的前一个对象保持静态,我无法对其执行任何操作。你可以给我一个解决方案,当我触摸它时,移动,缩放,旋转我想要的物体吗?

1 个答案:

答案 0 :(得分:1)

看到你没有发布任何代码,很难提供准确的答案。

但是,为了跟踪您想要使用的当前SCNNode,当您加载模型等时,您可以将其存储为变量,例如:

var currentNode: SCNNode!

您还可以在加载模型时使用节点的name属性,以便对其进行更具体的引用。

以下是执行此操作的示例:

/// Example Of Loading An SCNScene & Setting It As The Current Node
func loadModel(){

        let modelPath = "Character.scn"

        //1. Get The Reference To Our SCNScene & Get The Model Root Node
        guard let model = SCNScene(named: modelPath),
            let modelObject = model.rootNode.childNode(withName: "Root", recursively: false) else { return }

        //2. Scale It
        modelObject.scale = SCNVector3(0.4, 0.4, 0.4)

        //3. Add It To The Scene & Position It 1.5m Away From The Camera
        augmentedRealityView.scene.rootNode.addChildNode(modelObject)
        modelObject.position = SCNVector3(0, 0, -1.5)

        //4. Set It As The Current Node & Assign A Name
        currentNode = modelObject
        currentNode.name = "Character"

 }

您还可以使用SCNHitTest

  

沿您指定的光线查找SCNGeometry对象。对于每一个   在射线和几何体之间的交集,SceneKit创建了一个   命中测试结果,提供有关SCNNode对象的信息   包含几何和交叉点的位置   几何的表面。

这可以用来区分哪个节点被命中,例如:

/// Detects A Tap On An SCNNode
///
/// - Parameter gesture: UITapGestureRecognizer
@objc func detectTap(_ gesture: UITapGestureRecognizer){

    //1. Get The Current Touch Point
    let currentTouchPoint = gesture.location(in: self.augmentedRealityView)

    //2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
    guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }

    if nodeHitTest.node == currentNode{
        print("The Current Node Has Been Touched")
    }

    //Or To See Which Node Has Been Touched
    if nodeHitTest.node.name == "The Model"{
        print("The Model Has Been Touched")
    }
}

您可以处理此问题的另一种方法是向您的视图添加UITapGestureRecognizer,并根据结果启用互动,例如以这种方式设置currentNode:

/// Detects A Tap On An SCNNode & Sets It As The Current Node
///
/// - Parameter gesture: UITapGestureRecognizer
@objc func detectTap(_ gesture: UITapGestureRecognizer){

    //1. Get The Current Touch Point
    let currentTouchPoint = gesture.location(in: self.augmentedRealityView)

    //2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
    guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }

    //2b. Set It As The Current Node
    currentNode = nodeHitTest.node
}

然后你可以应用逻辑来确保只有currentNode移动等:

/// Moves An SCNNode
///
/// - Parameter gesture: UIPanGestureRecognizer
@objc func moveNode(_ gesture: UIPanGestureRecognizer) {

    //1. Get The Current Touch Point
    let currentTouchPoint = gesture.location(in: self.augmentedRealityView)

    //2. If The Gesture State Has Begun Perform A Hit Test To Get The SCNNode At The Touch Location
    if gesture.state == .began{

        //2a. Perform An SCNHitTest To Detect If An SCNNode Has Been Touched
        guard let nodeHitTest = self.augmentedRealityView.hitTest(currentTouchPoint, options: nil).first else { return }

        //2b. Get The SCNNode Result
        if nodeHitTest.node == currentNode{

            //3a. If The Gesture State Has Changed Then Perform An ARSCNHitTest To Detect Any Existing Planes
            if gesture.state == .changed{

                //3b. Get The Next Feature Point Etc
                guard let hitTest = self.augmentedRealityView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }

                //3c. Convert To World Coordinates
                let worldTransform = hitTest.worldTransform

                //3d. Set The New Position
                let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z)

                //3e. Apply To The Node
                currentNode.simdPosition = float3(newPosition.x, newPosition.y, newPosition.z)

            }

        }
    }
}

这应该足以让你指出正确的方向......