Управление жестами между набором спрайтов и набором сцен - PullRequest
1 голос
/ 31 марта 2020

Я пытаюсь создать сферу с выбираемыми плитками сетки. Сфера должна иметь возможность вращаться и увеличивать масштаб, в то же время позволяя выбирать плитки сетки. Из того, что я понимаю, это можно сделать, используя SceneKit Sphere и установив diffuse.contents равным Sprite Kit Scene.

В настоящее время у меня есть сфера со сценой набора спрайтов в качестве наложения текстуры. Я могу создавать тесты попаданий, которые распознают координаты x, y на сфере, но на самом деле я не выбираю плитки. «узел не имеет имени» печатает, я предполагаю, что выбранные узлы будут частью SceneKit, а не текстуры Sprite Kit.

Я создал этот проект как представление платформы для приложения Flutter, если это что-то изменит. Также была создана сцена Sprite Kit в файле .scn.

Есть предложения?


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

            }
        }

}

1 Ответ

0 голосов
/ 04 апреля 2020

Назовите ваши узлы, когда вы их создаете -> node.name = "x". В зависимости от нескольких вещей, но, как правило, рекомендуется называть свои узлы уникально (камеры и т. Д. c.) На случай, если вам придется пройтись по куче узлов, чтобы посмотреть, что они из себя представляют. Не уверен, что вы вернетесь домой, но это может быть первой проблемой. «Выглядит» так, как будто вы читаете эти сообщения: 35023170, поэтому кажется, что вы движетесь в правильном направлении.

Возможно, вам нужно выполнить итерацию для нескольких результатов, чтобы быть уверенным, что вы получите желаемый результат:

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