当isUserInteractionEnabled为false时,SKSpriteNode不允许触摸通过

我试图通过使用SKSpriteNode在SpriteKit中创build一个覆盖。 但是,我想触摸通过覆盖,所以我设置isUserInteractionEnabled为false。 但是,当我这样做时, SKSpriteNode似乎仍然吸收了所有的触摸,并且不允许底层节点做任何事情。

这是我正在谈论的一个例子:

 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) } } 

我已经尝试了SKSpriteNode子类SKSpriteNode并手动将touch事件委派给适当的节点,但这会导致很多奇怪的行为。

任何帮助将非常感激。 谢谢!

你需要小心zPosition。 有可能走到现场,使事情变得复杂。

更糟的是触摸事件的顺序。 我记得读到它是基于节点树,而不是zPosition。 禁用场景触摸,你应该看到的结果。

这就是现在说的:

命中testing顺序与绘制顺序相反在场景中,当SpriteKit处理触摸或鼠标事件时,它会走过场景以find最接近该事件的节点。 如果该节点不需要该事件,则SpriteKit会检查下一个最近的节点,依此类推。 命中testing的顺序基本上与绘制顺序相反。

对于在命中testing期间要考虑的节点,其userInteractionEnabled属性必须设置为YES。 除场景节点以外的任何节点的默认值为NO。 想要接收事件的节点需要从其父类(iOS上的UIResponder和OS X上的NSResponder)实施适当的响应方法。 这是less数必须在SpriteKit中实现特定于平台的代码的地方之一。

但是情况并非总是如此,因此您需要检查8,9和10之间的一致性

阅读您发现的实际来源:

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

但是这指的是触摸的内部节点方法。 默认情况下, isUserInteractionEnabledfalse,那么默认情况下,触摸一个像覆盖SKSpriteNode的孩子是一个简单的触摸处理主(或父)类(对象在这里,存在,但如果你没有实施任何行动,你只需触摸它)

要通过触摸覆盖您可以执行下面的代码到您的GameScene记住也不要使用-1作为zPosition因为它意味着它在您的场景之下。

PS :我已经添加了一个name给你的精灵来回想touchesBegan但你可以创build全局variables到你的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) } } } } } } }