【问题标题】:Moving a node in SceneKit using touch使用触摸在 SceneKit 中移动节点
【发布时间】:2016-09-15 14:51:45
【问题描述】:

我正在尝试通过触摸移动 SceneKit 中的节点。 我在这里使用代码:Move a specific node in SceneKit using touch

我遇到的问题是,每次我启动 panGesture 时,我触摸的对象都会转到场景的左角以开始移动。将其从该位置移动并释放是可以的,只是在每次平移开始时,对象都会从左角重置。如果我缩小,它会从这个新缩放级别的角落重新设置。

我的代码是:

func CGPointToSCNVector3(view: SCNView, depth: Float, point: CGPoint) -> SCNVector3 {
    let projectedOrigin = view.projectPoint(SCNVector3Make(0, 0, depth))
    let locationWithz   = SCNVector3Make(Float(point.x), Float(point.y), projectedOrigin.z)
    return view.unprojectPoint(locationWithz)
}
func dragObject(sender: UIPanGestureRecognizer){
    if(movingNow){
        let translation = sender.translationInView(sender.view!)
        var result : SCNVector3 = CGPointToSCNVector3(objectView, depth: tappedObjectNode.position.z, point: translation)
        tappedObjectNode.position = result
    }
    else{
        let hitResults = objectView.hitTest(sender.locationInView(objectView), options: nil)
        if hitResults.count > 0 {
            movingNow = true
        }
    }
    if(sender.state == UIGestureRecognizerState.Ended) {
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    let scnView = objectView
    scnView.backgroundColor = UIColor.whiteColor()
    scnView.autoenablesDefaultLighting = true
    scnView.allowsCameraControl = true

在调用 dragObject 之前,我暂时禁用了 allowCameraControl 的平移功能:

globalPanRecognizer = UIPanGestureRecognizer(target: self, 
    action:#selector(ViewController.dragObject(_:)))
objectView.addGestureRecognizer(globalPanRecognizer)

这些是第一次调用 CGPointToSCNVector3 中的值:

  • tappedObjectNode 的初始值:SCNVector3(x: 0.100000001, y: 0.100000001, z: 3.0)
  • projectedOrigin : SCNVector3(x: 261.613159, y: 285.530396, z: 0.949569583) - 这是异常大的
  • CGPointToSCNVector3 返回的值:SCNVector3(x: 1.03418088, y: 1.9734658, z: 4.64346933)

我玩过 CGPointToSCNVector3 的不同变体,但没有运气。 这种行为的原因是什么? 谢谢,

【问题讨论】:

  • 你好,所以这不是由于行allowCameraControl,因为我评论了该行并获得了相同的行为。我也不知道您是如何评论代码的,我一直在尝试这样做。谢谢
  • 我提到的 SO 链接的评论中链接到的 @rickster 代码的行为相同。 if(movingNow){ let translation = sender.translationInView(sender.view!) var offset = objectView.unprojectPoint(SCNVector3Make(Float(translation.x), Float(translation.y), globalProjectedOrigin.z))//步骤5 tappedObjectNode .position.x = globalOffset.x + offset.x // 第 6 步,y 和 z } else{ let hitResults = objectView.hitTest(sender.locationInView(objectView), options: nil) ..next comment }
  • 继续:` if hitResults.count > 0 { globalWorldCoordinates = hitResults[0].worldCoordinates // 步骤 2 globalProjectedOrigin = objectView.projectPoint(globalWorldCoordinates)// 步骤 3 globalOffset.x = globalWorldCoordinates.x - tappedObjectNode.position.x // 第 4 步,以及 y 和 z MovingNow = true } `(无法确定此处的代码格式,抱歉)

标签: ios swift scenekit


【解决方案1】:

解决方案是将sender.translationInView(sender.view!) 更改为sender.translationInView(self.view!)

【讨论】:

  • 我遇到了同样的问题,但上述解决方案对我不起作用。
  • 你能帮助我如何获得“tappedObjectNode”节点以及你在哪里设置。
  • 这里也一样。上述解决方案对我不起作用。它仍然移动到屏幕的左角
【解决方案2】:

Swift 4.1 / Xcode 9.3 / iOS 11.3

// node that you want the user to drag
var tappedObjectNode = SCNNode()

// the SCNView
@IBOutlet weak var sceneView: SCNView!

// the scene
let scene = SCNScene()

//helper
func CGPointToSCNVector3(view: SCNView, depth: Float, point: CGPoint) -> SCNVector3 {
    let projectedOrigin = view.projectPoint(SCNVector3Make(0, 0, depth))
    let locationWithz   = SCNVector3Make(Float(point.x), Float(point.y), projectedOrigin.z)
    return view.unprojectPoint(locationWithz)
}

// gesture handler
var movingNow = false
@objc func dragObject(sender: UIPanGestureRecognizer){
if(movingNow){
        let translation = sender.translation(in: sender.view!)
        var result : SCNVector3 = CGPointToSCNVector3(view: sceneView, depth: tappedObjectNode.position.z, point: translation)    
        tappedObjectNode.position = result
    } else {
        // view is the view containing the sceneView
        let hitResults = sceneView.hitTest(sender.location(in: view), options: nil)
        if hitResults.count > 0 {
            movingNow = true
        }
    }
}


// in viewDidLoad
sceneView.scene = scene

let panner = UIPanGestureRecognizer(target: self, action: #selector(dragObject(sender:)))
sceneView.addGestureRecognizer(panner)

【讨论】:

    猜你喜欢
    • 2015-06-07
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    • 2018-10-30
    • 2021-08-25
    • 2017-07-02
    相关资源
    最近更新 更多