SceneKit 中声明的 func hitTest 导致 Playground 崩溃

Posted

技术标签:

【中文标题】SceneKit 中声明的 func hitTest 导致 Playground 崩溃【英文标题】:func hitTest declared in SceneKit causes crash in Playground 【发布时间】:2017-03-22 19:24:34 【问题描述】:

我在操场上创建一个场景并使用 hitTest (func hitTest(_ point: CGPoint, options: [SCNHitTestOption : Any]? = nil) -> [SCNHitTestResult]) 函数来确定其中一个节点是否已被触摸,但只有当节点被触摸时,它才会导致操场上的模拟器崩溃。使用 xcode 的 ios 项目上的相同代码不会发生这种情况。

func panGesture(sender: UIPanGestureRecognizer) 
    sender.view

    let translation = sender.translation(in: sender.view!)

    var newAngleX = (Float)(translation.y)*(Float)(M_PI)/180.0
    newAngleX += currentXAngle
    var newAngleY = (Float)(translation.x)*(Float)(M_PI)/180.0
    newAngleY += currentYAngle

    if (sender.numberOfTouches>0)

        var point = sender.location(in: self)

        print(point)

        let hit = self.hitTest(point, options: nil)

        let node = hit.first?.node

        node?.eulerAngles.x = newAngleX
        node?.eulerAngles.y = newAngleY

        if(sender.state == UIGestureRecognizerState.ended) 
            currentXAngle = newAngleX
            currentYAngle = newAngleY
        

    


【问题讨论】:

有栈吗? 没有.. Xcode 上新游戏项目的示例代码与在 playground 上报告的 sceneKit 会产生同样的问题 发布您的整个 Playground 文件?或者至少足以证明问题? @DonMag [dropbox.com/s/1bmhsdaczl3rosi/cubeRotate.playground.zip?dl=0] 【参考方案1】:

这在 Playground 中运行得非常、非常、非常慢……但也许还有其他事情发生。无论如何,如果你用这个替换你的func panGesture(sender: UIPanGestureRecognizer),它至少应该让你在 Playground 中运行它而不会崩溃。

func panGesture(sender: UIPanGestureRecognizer) 
    sender.view

    let translation = sender.translation(in: sender.view!)

    var newAngleX = (Float)(translation.y)*(Float)(M_PI)/180.0
    newAngleX += currentXAngle
    var newAngleY = (Float)(translation.x)*(Float)(M_PI)/180.0
    newAngleY += currentYAngle

    let point = sender.location(in: self)
    print(point)

    // important
    guard let hit = self.hitTest(point, options: nil) as? [SCNHitTestResult] else  return 

    // and, don't go in here if hit.count == 0, because it won't have a .first
    if (sender.numberOfTouches > 0 && hit.count > 0)

        let node = hit.first?.node

        node?.eulerAngles.x = newAngleX
        node?.eulerAngles.y = newAngleY

        if(sender.state == UIGestureRecognizerState.ended) 
            currentXAngle = newAngleX
            currentYAngle = newAngleY
        

    


【讨论】:

以上是关于SceneKit 中声明的 func hitTest 导致 Playground 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

带有 SceneKit SCNProgram 的金属着色器

SceneKit 中的“simd”前缀是啥意思?

在一行中声明和定义一个委托(不使用 Action/Func)

func和Expression

将 func loadview 中声明的 self.view 约束到视图控制器的部分区域

一个弱声明问题