How to Overlay a Skscene Over a Scnscene in Swift

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



Leave a reply



Submit