I am working on creating annotations using overlaySKScene
something similar to this(https://sketchfab.com/models/1144d7be20434e8387a2f0e311eca9b1#). I followed https://github.com/halmueller/ImmersiveInterfaces/tree/master/Tracking%20Overlay to create the overlay.
But in the provided example, they are creating only one annotation and it is static. I want to create multiple annotations dynamically based on the number of child nodes we have and also should be able to position annotation on top of respective child node. How to achieve this?
I am adding overlay like below,
sceneView.overlaySKScene = InformationOverlayScene(size: sceneView.frame.size)
where InformationOverlayScene is the SKScene
in which i have added two childnodes
to create one annotation.
Create an array with the annotation sprites that is mapped to the childnodes array, and then do something like the following:
func renderer(_ aRenderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
let scnView = self.view as! SCNView
//for each character
for var i in 0...inBattleChars.count-1 {
let healthbarpos = scnView.projectPoint(inBattleChars[i].position)
battleSKO.healthbars[i].position = CGPoint(x: CGFloat(healthbarpos.x), y: (scnView.bounds.size.height-10)-CGFloat(healthbarpos.y))
}
}
Before every frame is rendered this updates the position of an SKSprite (in healthBars) for each SCNNode in inBattleChars. The key part is where projectPoint is used to get the SK overlay scene's 2D position based on the SCNNode in the 3D scene.
To prevent the annotations of non-visible nodes from showing up (such as childnodes on the back side of the parent object) use the SCNRenderer’s nodesInsideFrustum(of:) method.
You can add a SKScene
or a CALayer
as a material property.
You could create a SCNPlane
with a specific width and height and add a SpriteKit scene as the material.
You can find an example here.
Then you just position the plane where you want it to be and create and delete the annotations as you need them.