SKNode 上的 UITapGestureRecognizer:将坐标从 UIView 转换为 SKNode

UITapGestureRecognizer on SKNode: Converting Coordinates from UIView to SKNode

我在 UIView 上有一个 UITapGestureRecognizer 和一个 UIPanGestureRecognizer,上面有一个 SKScene。平移手势识别器从左到右移动一个 SKNode,我希望 Tap 手势识别器检测平移的 SKNode 的子节点。平移工作正常,但我在检测点击时遇到问题 - Tap Gesture 触发了相关方法,但我不确定如何将坐标从视图转换为场景到节点以检测点击是否在其中之一子节点。

UIView(带手势)→ SKScene → 平移节点 → 平移节点的子节点

如何检查点击手势的触摸坐标是否是任何给定的 SKNode?

-(void)tapAction:(UITapGestureRecognizer*)sender{
if (sender.state == UIGestureRecognizerStateEnded)
{
    // handling code
    CGPoint touchLocation = [sender locationOfTouch:0 inView:sender.view];
    NSLog(@"TAP %@", NSStringFromCGPoint(touchLocation)
          );
    for (SKLabelNode *node in _containerNode.children) {

        if ([node containsPoint:[node convertPoint:touchLocation fromNode:self.parent]]) {
            //This is where I want the tap to be detected.
        }

        CGPoint checkPoint = [node convertPoint:touchLocation fromNode:self.scene];
        NSLog(@"CheckPoint %@", NSStringFromCGPoint(checkPoint)
              );
        //NSLog(@"iterating nodes");
        if ([node containsPoint:checkPoint]) {
            NSLog(@"touch match %@", node);

        }
    }
}

}

我以前没有使用过 SceneKit,但从文档看来您需要使用 SKView 方法 convertPoint:toScene: 将手势识别器的点击坐标从视图坐标转换为场景坐标。然后您需要点击测试场景中的节点以确定哪个节点被点击。

您应该使用 convertPointFromView:

将视图坐标转换为场景坐标
CGPoint touchLocationInView = [sender locationOfTouch:0 inView:sender.view];
CGPoint touchLocationInScene = [self convertPointFromView:touchLocationInView];

然后你可以检测哪个标签节点被点击了,

for (SKLabelNode *node in self.children) {

    if ([node containsPoint:touchLocationInScene]) {
        //This is where I want the tap to be detected.
    }

}

最后,我需要根据建议再执行几个步骤 - 从 SKView → SKScene 转换到包含我正在测试的节点的 SKNode。

    CGPoint touchLocation           = [sender locationOfTouch:0 inView:sender.view];
    CGPoint touchLocationInScene    = [[self.scene view] convertPoint:touchLocation toScene:self.scene];
    CGPoint touchLocationInNode     = [self.scene convertPoint:touchLocationInScene toNode:_containerNode];