How can I overlay a SKScene over a SCNScene in Swift?
The SpriteKit overlay goes on the SceneKit view, not on the SceneKit scene. This is a bit confusing because you're overlaying a scene on a view.
I see several possible error sources:
self.sceneView = MainScene(view: self.view))
as defined returns an SCNScene
. You're assigning that to a property that expects an SCNView
.
The line
scnView = view as! SCNView
will crash unless view
returns a properly connected SCNView
instance. But the init
definition you've written expects a UIView
.
Somewhere, you need to have your view be an SCNView
. That view, because it conforms to protocol SCNSceneRenderer
, will have an overlaySKScene
property on it (overlaySKScene
comes from that protocol, not from SCNView
). That's where you can assign your SKScene
instance.
If you have done that, then your code would look something like
scnView.scene = self
scnView.overlaySKScene = theSKScene
I have a simple example of an SKScene
overlaid on an SCNView
at https://github.com/halmueller/ImmersiveInterfaces/tree/master/Tracking%20Overlay
See also How do I create a HUD on top of my Scenekit.scene.
Detect SpriteKit button press overlay from SceneKit
1) By having isUserInteractionEnabled set to false on your overlay, your overlay is never going to receive touch events.
2) With you manually scaling, you open yourself up to screwing around with your math. SpriteKit is designed to handle scaling for you, that is why scaleMode exists. It makes a lot more sense to scale once at the very end up process, then to constantly scale every little thing.
Do the following changes, and it should work for you.
Set
overlayScene.isUserInteractionEnabled = true
To allow your scene to receive touches,
then clean up your code:
class OverlayScene : SKScene {
var timeLabel:SKLabelNode!
var mainMenu:SKSpriteNode!
override init(size: CGSize) {
super.init(size:size)
}
convenience override init() {
self.init(size: CGSize(width:1024,height:768))
//setup the overlay scene
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
//automatically resize to fill the viewport
self.scaleMode = .fill
// Initialize the Score
timeLabel = SKLabelNode(text: "Time: 0")
timeLabel.position = CGPoint(x: size.width * 0.35, y: size.height*0.45)
timeLabel.fontName = "AmericanTypewriter-Bold"
timeLabel.fontSize = 36
timeLabel.fontColor = UIColor.white
addChild(timeLabel)
mainMenu = SKSpriteNode(imageNamed: "MainMenu_ButtonHighlighted-IpadMini.png")
mainMenu.anchorPoint = CGPoint(x: 0, y: 0)
mainMenu.position = CGPoint(x: size.width * 0.35, y: size.height*0.45)
mainMenu.isUserInteractionEnabled = false
mainMenu.zPosition = 0
addChild(mainMenu)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.location(in: self)
if mainMenu == self.atPoint(location) {
print("Main Menu Touch Began")
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.location(in: self)
if mainMenu == self.atPoint(location) {
print("Main Menu Touch Ended")
}
}
}
}
and use:
sceneView.overlaySKScene = OverlayScene()
swift/scenekit problems getting touch events from SCNScene and overlaySKScene
This is "lifted" straight out of Xcode's Game template......
Add a gesture recognizer in your viewDidLoad:
// add a tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action:
#selector(handleTap(_:)))
scnView.addGestureRecognizer(tapGesture)
func handleTap(_ gestureRecognize: UIGestureRecognizer) {
// retrieve the SCNView
let scnView = self.view as! SCNView
// check what nodes are tapped
let p = gestureRecognize.location(in: scnView)
let hitResults = scnView.hitTest(p, options: [:])
// check that we clicked on at least one object
if hitResults.count > 0 {
// retrieved the first clicked object
let result: AnyObject = hitResults[0]
// result.node is the node that the user tapped on
// perform any actions you want on it
}
}
overlaySKSScene not working: SpriteKit scene does not appear in SCNView
The following code works for me after setting up a default SceneKit project.
override func viewDidLoad() {
super.viewDidLoad()
let scene = SCNScene(named: "art.scnassets/ship.scn")!
let scnView = self.view as! SCNView
scnView.scene = scene
let skScene = SKScene(size: UIScreen.main.bounds.size)
let node = SKSpriteNode(imageNamed: "testImage.png")
skScene.addChild(node)
scnView.overlaySKScene = skScene
scnView.overlaySKScene!.scaleMode = .resizeFill
}
The overlay view wouldn't show up unless the SCNScene
was set on the view, and the background colour of the SKScene
had no effect.
Related Topics
Uiwebview Stringbyevaluatingjavascriptfromstring Hangs on iOS5.0/5.1 When Called Using Gcd
Animating Calayer's Shadowpath Property
How to Get an Error Description When Playback Fails on Mpmovieplayercontroller
How Could You Make a Uilabel Wrap Around an Image (Like Shown)
iOS Multiple Right and Left Align on Same Line
Xamarin "The Executable Was Signed with Invalid Entitlements"
Collectionview Duplicate Cell When Loading More Data
Uiactivityviewcontroller Completion Handler Returns Success When Tweet Has Failed
iOS Google Sdk Map Cannot Create Dotted Polylines
Cancel Button Is Not Shown in Uisearchbar
How to Hide "Back to Safari" from Status Bar in iOS9
Autolayout: Uiview Within Uiview Has Incorrect Frame
Disable Autorotate on a Single Subview in iOS8
Get Created Date and Last Login Date from Firuser with Firebase 3