SKSpriteNode does not miss touch when isUserInteractionEnabled false

I am trying to create an overlay in SpriteKit using SKSpriteNode . However, I want the strokes to go through the overlay, so I set isUserInteractionEnabled to false. However, when I do this, SKSpriteNode still seems to absorb all the touches and prevent the base nodes from doing anything.

Here is an example of what I am saying:

 class TouchableSprite: SKShapeNode { override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print("Touch began") } } class GameScene: SKScene { override func sceneDidLoad() { // Creat touchable let touchable = TouchableSprite(circleOfRadius: 100) touchable.zPosition = -1 touchable.fillColor = SKColor.red touchable.isUserInteractionEnabled = true addChild(touchable) // Create overlay let overlayNode = SKSpriteNode(imageNamed: "Fade") overlayNode.zPosition = 1 overlayNode.isUserInteractionEnabled = false addChild(overlayNode) } } 

I tried a subclass of SKSpriteNode and manually delegated touch events to the corresponding nodes, but this leads to a lot of weird actions.

Any help would be greatly appreciated. Thanks!

+1
ios swift touch sprite-kit
source share
2 answers

You need to be careful with zPosition. You can go behind the scenes, which complicates the situation.

The worse the touch order. I remember reading that it is based on the node tree, not zPosition. Turn off the touch of the scene and you will see the results.

Here is what he says now:

The hit test order is the reverse order of drawing. In a scene, when SpriteKit processes touch or mouse events, it scans through the scene to find the nearest node that wants to receive the event. If this node doesnt want an event, SpriteKit checks the next nearest node, etc. the order in which hit testing is processed is essentially the reverse of the drawing order.

For a node to be considered during impact testing, its userInteractionEnabled property must be set to YES. The default value is NO for any node, except for the node scene. A node that wants to receive events needs to implement appropriate response methods from its parent class (UIResponder on iOS and NSResponder on OS X). This is one of several places where you must implement platform-specific code in SpriteKit.

But this may not always be the case, so you will need to check between 8, 9 and 10 for consistency

+3
source share

Reading the actual sources you will find:

 /** Controls whether or not the node receives touch events */ open var isUserInteractionEnabled: Bool 

but this applies to internal node touch methods. By default, isUserInteractionEnabled false , then touching a child similar to your SKSpriteNode overlay is by default a simple touch to the main (or parent) class (the object exists here, but if you do not perform any actions, just touch it)

To go through the overlay with a touch, you can implement code like the one below to your GameScene . Repeat also do not use -1 as zPosition , because it means that it is below your scene.

PS . I added name for sprites to call it on touchesBegan , but you can create global variables in GameScene :

 override func sceneDidLoad() { // Creat touchable let touchable = TouchableSprite(circleOfRadius: 100) touchable.zPosition = 0 touchable.fillColor = SKColor.red touchable.isUserInteractionEnabled = true touchable.name = "touchable" addChild(touchable) // Create overlay let overlayNode = SKSpriteNode(imageNamed: "fade") overlayNode.zPosition = 1 overlayNode.name = "overlayNode" overlayNode.isUserInteractionEnabled = false addChild(overlayNode) } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print("GameScene Touch began") for t in touches { let touchLocation = t.location(in: self) if let overlay = self.childNode(withName: "//overlayNode") as? SKSpriteNode { if overlay.contains(touchLocation) { print("overlay touched") if let touchable = self.childNode(withName: "//touchable") as? TouchableSprite { if touchable.contains(touchLocation) { touchable.touchesBegan(touches, with: event) } } } } } } } 
+3
source share

All Articles