gpt4 book ai didi

ios - Spritekit 和 Scenekit 的 HitTest

转载 作者:搜寻专家 更新时间:2023-10-31 08:03:52 26 4
gpt4 key购买 nike

我有一个看起来很基本的 ViewController 和一个 SCNView,它有一个 overlaySKScene

我遇到的问题是我希望在底层self.scene(gameScene 在下面的示例)如果它首先在叠加场景的 SpriteKit 节点中检测到。

对于以下内容,即使点击发生在 SKOverlay 场景节点 actionButtonNode 上,两个场景都报告发生了点击。

View Controller

import UIKit
import SceneKit

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()

sceneView = self.view as? SCNView
gameScene = GameScene()

let view = sceneView
view!.scene = gameScene
view!.delegate = gameScene as? SCNSceneRendererDelegate
view!.overlaySKScene = OverlayScene(size: self.view.frame.size)

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTap(_:)))
tapGesture.cancelsTouchesInView = false
view!.addGestureRecognizer(tapGesture)
}

@objc func handleTap(_ sender:UITapGestureRecognizer) {
let projectedOrigin = self.sceneView!.projectPoint(SCNVector3Zero)
let taplocation = sender.location(in: self.view!)
let opts = [ SCNHitTestOption.searchMode:1, SCNHitTestOption.ignoreHiddenNodes:0 ]
let hitList = self.sceneView!.hitTest(taplocation, options: opts)
if hitList.count > 0 {
for hit in hitList {
print("hit:", hit)
}
}
}
}

叠加场景

import UIKit
import SpriteKit

class OverlayScene: SKScene {
var actionButtonNode: SKSpriteNode!

override init(size: CGSize) {
super.init(size: size)

self.backgroundColor = UIColor.clear

self.actionButtonNode = SKSpriteNode()
self.actionButtonNode.size = CGSize(width: size.width / 2, height: 60)
self.actionButtonNode.position = CGPoint(x: size.width / 2, y: 80)
self.actionButtonNode.color = UIColor.blue
self.addChild(self.actionButtonNode)
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let location = touch?.location(in: self)
if self.actionButtonNode.contains(location!) {
print("actionButtonNode touch")
}
}
}

最佳答案

我没有适合您的带有代码的奇特解决方案,但有两种可能的解决方法:

一个。通过处理主视图 Controller 中的所有触摸来避免这种情况。我也用 SceneKit 和 SpriteKit 覆盖来做到这一点,将逻辑放在覆盖场景之外,并仅将其用于预期目的(图形覆盖,而不是常规的交互式 SpriteKit 场景)。您可以测试是否在 Scenekit View Controller 中点击了操作按钮或任何其他按钮。如果没有按钮被击中,则 3D 场景被击中。

添加一个 bool 到主 Scenekit View Controller ,isHandledInOverlay 并在按钮被触摸时在 SpriteKit 场景中设置它。在主 Scenekit View Controller 中,检查 handletap 中的 bool 并返回,如果为真,则不执行任何操作。

根据评论编辑:我只是建议移动这段代码:

if self.actionButtonNode.contains(location!) {
print("actionButtonNode touch")
}

到 ViewController 中的 handleTap 函数。您将必须制作一个包含 SKOverlayScene 的 var,它又将 actionButtonNode(和任何其他按钮)作为属性,因此在 handleTap 中您最终会得到如下内容:

if self.theOverlay.actionButtonNode.contains(taplocation) {
print("actionButtonNode touch")
} else if self.theOverlay.action2ButtonNode.contains(taplocation) {
print("action2ButtonNode touch")
} else if self.theOverlay.action3ButtonNode.contains(taplocation) {
print("action3ButtonNode touch")
} else {
//no buttons hit in 2D overlay, let's do 3D hittest:
let opts = [ SCNHitTestOption.searchMode:1, SCNHitTestOption.ignoreHiddenNodes:0 ]
let hitList = self.sceneView!.hitTest(taplocation, options: opts)
if hitList.count > 0 {
for hit in hitList {
print("hit:", hit)
}
}
}

因此,首先将 2D 轻敲位置与按钮的 2D 坐标进行比较,以查看它们是否被轻敲,如果没有,则使用 2D 轻敲位置来查看 3D 场景中的对象是否被轻敲使用 HitTest 。

编辑:只是在查看我自己的 (obj c) 代码并注意到我在主视图 Controller 中翻转 Y 坐标以获取 SKOverlay 中的坐标:

CGPoint tappedSKLoc = CGPointMake(location.x, self.menuOverlayView.view.frame.size.height-location.y);

您可能必须使用您提供给按钮节点的 contains 函数的位置来执行此操作。

关于ios - Spritekit 和 Scenekit 的 HitTest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48601305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com