Problems with fast / scenario mode of receiving touch events from SCNScene and overlaySKScene

Good afternoon, I'm trying to figure out how to get touch notifications with SCNNode and SKSpriteNode from SCNScene superimposed on SKScene.

import UIKit import SceneKit class GameViewController: UIViewController { var scnView:SCNView! var scnScene:SCNScene! var sprite: spritekitHUD! var cameraNode: SCNNode! var shape: SCNNode! override func viewDidLoad() { super.viewDidLoad() setupScene() } func setupScene() { scnView = self.view as! SCNView scnView.delegate = self scnView.allowsCameraControl = true scnScene = SCNScene(named: "art.scnassets/scene.scn") scnView.scene = scnScene sprite=spritekitHUD(size: self.view.bounds.size, game: self) scnView.overlaySKScene=sprite cameraNode = scnScene.rootNode.childNode(withName: "camera", recursively: true)! shape=scnScene.rootNode.childNode(withName: "shape", recursively: true) shape.name="ThreeDShape" } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { let touch = touches.first! let location = touch.location(in: scnView) let hitResults = scnView.hitTest(location, options: nil) if let result = hitResults.first { handleTouchFor(node: result.node) } } func handleTouchFor(node: SCNNode) { if node.name == "ThreeDShape" { print("SCNNode Touched") } } } 

This is my Spritekit overlay script.

 import Foundation import SpriteKit class spritekitHUD: SKScene{ var game:GameViewController! var shapeNode: SKSpriteNode! init(size: CGSize, game: GameViewController){ super.init(size: size) self.backgroundColor = UIColor.white let spriteSize = size.width/12 self.shapeNode= SKSpriteNode(imageNamed: "shapeNode") self.shapeNode.size = CGSize(width: spriteSize, height: spriteSize) self.shapeNode.position = CGPoint(x: spriteSize + 8, y: spriteSize + 8) self.shapeNode.name="test" self.game=game self.addChild(self.pauseNode) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch=touches.first else{ return } let location=touch.location(in: self) if self.atPoint(location).name=="test" { print("Spritekit node pressed") } } } 

so I can successfully receive notifications that my spritenode has been affected by my overlaySKScene, but I cannot figure out how to get a notification that my SCNode has been affected. If you do not have two functions, that is, someone has ideas, how can I handle 3D events simultaneously using two events?

Thanks for the help!

+4
source share
3 answers

This is "shot" directly from the Xcode game template ......

Add a gesture recognizer to your DidLoad view:

  // add a tap gesture recognizer let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:))) scnView.addGestureRecognizer(tapGesture) func handleTap(_ gestureRecognize: UIGestureRecognizer) { // retrieve the SCNView let scnView = self.view as! SCNView // check what nodes are tapped let p = gestureRecognize.location(in: scnView) let hitResults = scnView.hitTest(p, options: [:]) // check that we clicked on at least one object if hitResults.count > 0 { // retrieved the first clicked object let result: AnyObject = hitResults[0] // result.node is the node that the user tapped on // perform any actions you want on it } } 
+3
source

If you want to use the SKScene overlay of the SKScene element for custom controls (for example, you want to implement a button in the SKScene overlay that "consumes" to the touch), but also has touches that do not have to remove the controls that you need to go through and register in the base SCNView , you have to do this: set isUserInteractionEnabled to false on the SKScene overlay, but then true to any individual elements within this overlay that you'd like to act as buttons.

 let overlay = SKScene(fileNamed: "overlay") overlay?.isUserInteractionEnabled = false let pauseButton = overlay?.childNode(withName: "pauseButton") as? Button // Button is a subclass of SKSpriteNode that overrides touchesEnded pauseButton?.isUserInteractionEnabled = true sceneView.overlaySKScene = overlay 

If the user touches the button, button press events ( touchesBegan , touchesEnded , etc.) will fire and consume a touch (at the same time, gesture recognizers will still fire). However, if they touch only the button, the touch goes to the main SCNView.

+5
source

You can implement this method in spritekitHUD:

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { game.touchesBegan(touches, with: event) } 
0
source

Source: https://habr.com/ru/post/1272407/


All Articles