JP *_*shy 5 ios scenekit swift
我有一个似乎很基本的东西ViewController,SCNView其中有一个overlaySKScene。
我遇到的问题是,如果不首先在覆盖场景的SpriteKit节点中检测到该轻敲,则不希望在基础self.scene(gameScene在下面的示例中)中检测到该轻敲。
使用以下内容,两个场景都报告即使点击发生在SKOverlay场景节点上,也发生了命中actionButtonNode。
ViewController
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)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
叠加场景
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")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我没有\xe2\x80\x99t 有适合你的代码的奇特解决方案,但有两种可能的解决方法:
\n\nA。通过处理主视图控制器中的所有触摸来避免这种情况。我也使用 SceneKit 和 SpriteKit 覆盖来做到这一点,将逻辑保留在覆盖场景之外,并仅将其用于其预期目的(图形覆盖,而不是常规的交互式 SpriteKit 场景)。您可以测试是否在 Scenekit 视图控制器中点击了操作按钮或任何其他按钮。如果没有按下按钮,则按下 3D 场景。
\n\nb. 添加一个 bool 到主 Scenekit 视图控制器 isHandledInOverlay 并在按钮被触摸时将其设置在 SpriteKit 场景中。在主 Scenekit 视图控制器中检查 handletap 中的 bool 并返回,如果 true 则不执行任何操作。
\n\n根据评论进行编辑:\n我只是建议移动这段代码:
\n\nif self.actionButtonNode.contains(location!) {\n print("actionButtonNode touch")\n}\nRun Code Online (Sandbox Code Playgroud)\n\n到ViewController中的handleTap函数。您必须创建一个 var 来保存 SKOverlayScene,而 SKOverlayScene 又具有 actionButtonNode(以及任何其他按钮)作为属性,因此在 handleTap 中您最终会得到类似以下内容的内容:
\n\nif self.theOverlay.actionButtonNode.contains(taplocation) {\n print("actionButtonNode touch")\n} else if self.theOverlay.action2ButtonNode.contains(taplocation) {\n print("action2ButtonNode touch")\n} else if self.theOverlay.action3ButtonNode.contains(taplocation) {\n print("action3ButtonNode touch")\n} else {\n //no buttons hit in 2D overlay, let\'s do 3D hittest:\n let opts = [ SCNHitTestOption.searchMode:1, SCNHitTestOption.ignoreHiddenNodes:0 ]\n let hitList = self.sceneView!.hitTest(taplocation, options: opts)\n if hitList.count > 0 {\n for hit in hitList {\n print("hit:", hit)\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n因此,首先将 2D 点击位置与按钮的 2D 坐标进行比较,查看它们是否被点击,如果没有,则使用 2D 点击位置通过点击测试查看 3D 场景中的对象是否被点击。
\n\n编辑:只是查看我自己的(obj c)代码,注意到我翻转了主视图控制器中的 Y 坐标以获取 SKOverlay 中的坐标:
\n\nCGPoint tappedSKLoc = CGPointMake(location.x, self.menuOverlayView.view.frame.size.height-location.y);\nRun Code Online (Sandbox Code Playgroud)\n\n您可能必须使用提供给按钮节点的 contains 函数的位置来执行此操作。
\n| 归档时间: |
|
| 查看次数: |
567 次 |
| 最近记录: |