I'm making an app that adds an SCNText
to the ARSCNView
I've created called sceneView
. The text displays perfectly like this: (when the SCNText(string: "Test", extrusionDepth: CGFloat(0.01))
)
screenshot1:
but when the SCNText(string: "Test😂", extrusionDepth: CGFloat(0.01))
The SCNText
does not show the emoji:
screenshot2: This the complete code:
import UIKit
import SceneKit
import ARKit
import Vision
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet weak var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
// Create a new scene
let scene = SCNScene()
// Set the scene to the view
sceneView.scene = scene
// Enable Default Lighting - makes the 3D text a bit poppier.
sceneView.autoenablesDefaultLighting = true
sceneView.showsStatistics = true
// Tap Gesture Recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(gestureRecognize:)))
view.addGestureRecognizer(tapGesture)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
// Enable plane detection
configuration.planeDetection = .horizontal
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
// MARK: - ARSCNViewDelegate
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
DispatchQueue.main.async {
}
}
@objc func handleTap(gestureRecognize: UITapGestureRecognizer) {
self.create()
}
func create() {
// Get Screen Centre
let screenCentre : CGPoint = CGPoint(x: self.sceneView.bounds.midX, y: self.sceneView.bounds.midY)
let arHitTestResults : [ARHitTestResult] = sceneView.hitTest(screenCentre, types: [.featurePoint])
if let closestResult = arHitTestResults.first {
// Get Coordinates of HitTest
let transform : matrix_float4x4 = closestResult.worldTransform
let worldCoord : SCNVector3 = SCNVector3Make(transform.columns.3.x, transform.columns.3.y, transform.columns.3.z)
// Create 3D Text
let node : SCNNode = createNewParentNode()
sceneView.scene.rootNode.addChildNode(node)
node.position = worldCoord
}
}
func createNewParentNode(_ text : String) -> SCNNode {
let text = SCNText(string: "Test😂", extrusionDepth: CGFloat(0.01))
var font = UIFont(name: "Futura", size: 0.07)
font = font?.withTraits(traits: .traitBold)
text.font = font
text.alignmentMode = kCAAlignmentCenter
text.firstMaterial?.diffuse.contents = UIColor.orange
text.firstMaterial?.specular.contents = UIColor.white
text.firstMaterial?.isDoubleSided = true
text.chamferRadius = CGFloat(bubbleDepth)
let textNode = SCNNode(geometry: text)
textNode.pivot = SCNMatrix4MakeTranslation( positionx, positiony, positionz) // Don't worry about the positions they work fine
text.scale = SCNVector3Make(0.1, 0.1, 0.1)
let NodeParent = SCNNode()
NodeParent.addChildNode(text)
//Add More SCNNode's to NodeParent
return NodeParent
}
}
extension UIFont {
// Based on: https://stackoverflow.com/questions/4713236/how-do-i-set-bold-and-italic-on-uilabel-of-iphone-ipad
func withTraits(traits:UIFontDescriptorSymbolicTraits...) -> UIFont {
let descriptor = self.fontDescriptor.withSymbolicTraits(UIFontDescriptorSymbolicTraits(traits))
return UIFont(descriptor: descriptor!, size: 0)
}
}
I don't want to have to add it as a SKLabelNode
because I want to use the Storyboard for Collection Views later on.
Has it got something to do with the font I am using?
"SceneKit can create text geometry using any font and style supported by the Core Text framework, with the exception of bitmap fonts (such as those that define color emoji characters)".
However, you can still put emoji's onto a SCNNode (say box) as material/texture.
Edit: I created a Country flag ios App using emoji's a few months ago which is a good demo Youtube video - Country Flags iOS App