我正在与Swift和SceneKit合作开发一款iOS应用程序.当用户在屏幕上点击时,我想在SceneKit中用户刚刚点击的位置渲染一个点.我怎么能做到这一点?

我正在使用unprojectPoint()方法,但我的对象未呈现在预期位置.

我有一个场景视图,相机是这样的:

cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)

然后我在点击位置渲染这个点,如下所示:

func handleTap(_ gestureRecognize: UIGestureRecognizer) {
    // retrieve the SCNView
    let scnView = self.view as! SCNView
    
    // create dot
    let geo = SCNSphere(radius: CGFloat(0.1))
    geo.firstMaterial?.diffuse.contents = UIColor.red
    let dotNode = SCNNode(geometry: geo)
    
    let p = gestureRecognize.location(in: scnView)
    let uP = scnView.unprojectPoint(SCNVector3(p.x, p.y, 5))
    // HERE - how to set position for the dot ?
    dotNode.position = SCNVector3(uP.x, uP.y, 5)
    
    scnView.scene?.rootNode.addChildNode(dotNode)
}

这是我的Github回购:https://github.com/rudyhuynh/SceneKitExample

推荐答案

♪取消投影点♪

要在预期位置呈现点 node ,请使用以下方法.不要忘记,您正在以透视投影的方式查看场景.取消投影Z坐标为0.0的点将返回near clipping plane上的一个点.取消投影Z坐标为1.0的点将返回far clipping plane上的一个点.

import SceneKit

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()            
        let sceneView = self.view as! SCNView
        sceneView.scene = SCNScene()
        sceneView.backgroundColor = UIColor.black
                
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.simdPosition = simd_float3(0, 0, 1)
        sceneView.scene?.rootNode.addChildNode(cameraNode)
        
        let tapGesture = UITapGestureRecognizer(target: self,
                                                action: #selector(tap))
        sceneView.addGestureRecognizer(tapGesture)
    }

    @objc func tap(_ gestureRecognizer: UITapGestureRecognizer) {
        let scnView = self.view as! SCNView
        
        let geo = SCNSphere(radius: 0.01)
        geo.firstMaterial?.diffuse.contents = UIColor.white
        let dotNode = SCNNode(geometry: geo)

        let point = gestureRecognizer.location(in: scnView)
        let unprojected = scnView.unprojectPoint(.init(point.x, point.y, 0))
 
        dotNode.position = SCNVector3(unprojected.x, unprojected.y, -0.01)
        scnView.scene?.rootNode.addChildNode(dotNode)
    }
}

enter image description here

要在正交投影中运行摄影机,请使用:

cameraNode.camera?.usesOrthographicProjection = true

Ios相关问答推荐

如何保持拖动预览与原始项目完全相同?

如何使视图完全适合屏幕,而不会在旋转时溢出手机屏幕的边界?

自定义油漆圆角三角形

如何通过S定义的对象设置删除基于块的观察者的测试?

如何删除点击时按钮的不透明动画?

iOS设备网页自动化中,在向字段发送文本后未启用按钮

NSOperation 有延迟 - 它是异步的还是同步的?

如何让替换视图淡入旧视图而不是交叉淡入淡出?

具有多个目标的应用程序的动态内容

转换在 NavigationView 中不起作用

iOS,Swift 5,AppDelegate open url / .onOpenUrl - 如何找到调用我的自定义方案的调用应用程序

如何将私钥添加到分发证书?

如何在 Swift 3 中根据 UIImage 的大小/比率调整 UIImageView 的大小?

iPhone 6 和 6 Plus 媒体查询

由于 NSInvalidUnarchiveOperationException 导致 iOS11 WKWebview 崩溃

以编程方式 Select UITextField 中的所有文本

用户拒绝使用后如何提示用户打开位置服务

从故事板导航到其他 Swift 1.2 文件时 Xcode 6.3 崩溃

为给定的 UIColor 获取更亮和更暗的 colored颜色 变化

在 SKScene 中设置按钮