简体   繁体   English

管理 Sprite Kit 和 Scene Kit 之间的手势

[英]Manage Gestures Between Sprite Kit and Scene Kit

I am trying to create a sphere with selectable grid tiles.我正在尝试创建一个带有可选网格图块的球体。 The sphere should be able to rotate and zoom in, while still allowing grid tiles to be selectable.球体应该能够旋转和放大,同时仍然允许选择网格图块。 From what I understand this can be accomplished by using a SceneKit Sphere and setting the diffuse.contents equal to a Sprite Kit Scene.据我所知,这可以通过使用 SceneKit Sphere 并将漫反射内容设置为等于 Sprite Kit 场景来实现。

Currently, I have the Sphere present with the Sprite Kit Scene as a texture overlay.目前,我将 Sphere 与 Sprite Kit 场景一起作为纹理叠加呈现。 I am able to create hit tests that recognize x,y coordinates on the sphere, but I am not actually selecting any tiles.我能够创建识别球体上 x,y 坐标的命中测试,但我实际上并没有选择任何图块。 "node has no name" is printing, I assume nodes selected would be part of SceneKit, not the Sprite Kit texture. “节点没有名称”正在打印,我假设选择的节点将是 SceneKit 的一部分,而不是 Sprite Kit 纹理。

I created this project as a platform view for a Flutter app, if that changes anything.我创建了这个项目作为 Flutter 应用程序的平台视图,如果这有什么改变的话。 Also the Sprite Kit Scene was created in a .scn file.此外,Sprite Kit 场景是在 .scn 文件中创建的。

Any suggestions?有什么建议?


public class SceneKitViewFactory: NSObject, FlutterPlatformViewFactory {

    public func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        print("returning scene kit view")

            return SceneKitView(frame, viewId: viewId, args: args)

    }

}


public class SceneKitView: NSObject, FlutterPlatformView {
    let frame: CGRect
    let viewId: Int64
    let myScene: SCNScene
    let scnView: SCNView
    var cameraNode: SCNNode!


    init(_ frame: CGRect, viewId: Int64, args: Any?) {
        self.frame = frame
        self.viewId = viewId
        self.scnView = SCNView()
        self.myScene = SCNScene()
        scnView.scene = myScene
        scnView.backgroundColor = .green

        super.init()

        createSphere()
        createSceneHelpers()
        createCamera()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
        tapGesture.cancelsTouchesInView = false
        scnView.addGestureRecognizer(tapGesture)
    }

    public func view() -> UIView {
        return scnView
    }

    private func createSphere() {

        let sphere = SCNSphere(radius: 1.0)
        let imageMaterial = SCNMaterial()

        let spriteKitScene  = SKScene(fileNamed: "GameScene")!
        spriteKitScene.isUserInteractionEnabled = true

        imageMaterial.diffuse.contents = spriteKitScene

        let sphereNode = SCNNode(geometry: sphere)
        sphereNode.geometry!.firstMaterial = imageMaterial

        myScene.rootNode.addChildNode(sphereNode)
    }

    private func createSceneHelpers() {
        scnView.showsStatistics = true
        scnView.allowsCameraControl = true
        scnView.autoenablesDefaultLighting = true
    }

    private func createCamera() {
        cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(x: 0, y: 0, z: 5)
        myScene.rootNode.addChildNode(cameraNode)
    }


     @objc func handleTap(_ gestureRecognize: UIGestureRecognizer) {


            let p = gestureRecognize.location(in: scnView)
            let hitResults = scnView.hitTest(p, options: [:])
            if hitResults.count > 0 {
            let result: SCNHitTestResult = hitResults[0]

            print(result.node.name ?? "node has no name")
            print(result.textureCoordinates(withMappingChannel: 0)) // This line is added here.
            print("x: \(p.x) y: \(p.y)") // <--- THIS IS WHERE I PRINT THE COORDINATES

            }
        }

}

Name your node(s) when you create them -> node.name = "x".创建节点时命名节点 -> node.name = "x"。 Depending on a few things, but generally a good practice to name your nodes uniquely (cameras, etc.) in case you have to iterate through a bunch of nodes to see what they are.取决于一些事情,但通常一个很好的做法是为您的节点命名唯一(相机等),以防您必须遍历一堆节点以查看它们是什么。 Not sure that gets you all of the way home, but that could be the first issue.不确定这会让你一路回家,但这可能是第一个问题。 "Looks" like you are reading these posts: 35023170 so it seems you're heading in the right direction. “看起来”您正在阅读这些帖子:35023170,所以您似乎正朝着正确的方向前进。

Might want to iterate for multiple results just to be sure you get the hit you want:可能想要迭代多个结果只是为了确保你得到你想要的命中:

let hitResults = gameScene.hitTest(location, options: hitTestOptions)
for vHit in hitResults
{
   if(vHit.node.name?.prefix(5) == "Panel")
   {
   ...
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM