ARKit-如何在另一个SCNNode中包含SCNText(语音气泡) [英] ARKit - How to contain SCNText within another SCNNode (speech bubble)
问题描述
我正在尝试在ARKit的气泡中创建带有简单文本的报价生成器.
I am trying to create a quote generator with simple text within a speech bubble in ARKit.
我可以用文本显示讲话泡泡,但是文本总是从中间开始,并在讲话泡泡之外溢出.
I can show the speech bubble with text, but the text always starts in the middle and overflows outside of the speech bubble.
任何帮助使它对准气泡的左上角并包裹在气泡中的方法,将不胜感激.
Any help getting it align in the top left of the speech bubble and wrapping within the speech bubble would be appreciated.
结果
课程
class SpeechBubbleNode: SCNNode {
private let textNode = TextNode()
var string: String? {
didSet {
textNode.string = string
}
}
override init() {
super.init()
// Speech Bubble
let plane = SCNPlane(width: 200.0, height: 100.0)
plane.cornerRadius = 4.0
plane.firstMaterial?.isDoubleSided = true
geometry = plane
// Text Node
textNode.position = SCNVector3(position.x, position.y, position.z + 1.0)
// textNode.position = convertPosition(SCNVector3(0.0, 0.0, 1.0), to: textNode)
// textNode.position = SCNVector3(0.0, 0.0, position.z + 1.0)
addChildNode(textNode)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
class TextNode: SCNNode {
private let textGeometry = SCNText()
var string: String? {
didSet {
updateTextContainerFrame()
textGeometry.string = string
}
}
override init() {
super.init()
textGeometry.truncationMode = CATextLayerTruncationMode.middle.rawValue
textGeometry.isWrapped = true
textGeometry.alignmentMode = CATextLayerAlignmentMode.left.rawValue
let blackMaterial = SCNMaterial()
blackMaterial.diffuse.contents = UIColor.black
blackMaterial.locksAmbientWithDiffuse = true
textGeometry.materials = [blackMaterial]
geometry = textGeometry
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
private func updateTextContainerFrame() {
let (min, max) = boundingBox
let width = CGFloat(max.x - min.x)
let height = CGFloat(max.y - min.y)
print("width :",max.x - min.x,"height :",max.y - min.y,"depth :",max.z - min.z)
textGeometry.containerFrame = CGRect(x: 0.0, y: 0.0, width: width, height: height)
// textGeometry.containerFrame = CGRect(origin: .zero, size: CGSize(width: 1.0, height: 1.0))
}
}
实施
private func makeSpeechBubbleNode(forBobbleheadNode bobbleheadNode: BobbleheadNode) {
let node = SpeechBubbleNode()
node.position = sceneView.scene.rootNode.convertPosition(bobbleheadNode.position, to: node)
node.scale = SCNVector3(0.002, 0.002, 0.002)
sceneView.scene.rootNode.addChildNode(speechBubbleNode)
self.speechBubbleNode = speechBubbleNode
speechBubbleNode.string = "Some random string that could be long and should wrap within speech bubble"
}
推荐答案
我遇到了同样的问题,最后我解决了以下问题:
I had the same problem and finally I have solved it as following:
-
创建一个SCNText并将其作为几何体添加到SCNNode:
Create a SCNText and add it as a geometry to SCNNode:
let string = "Coverin text with a plane :)"
let text = SCNText(string: string, extrusionDepth: 0.1)
text.font = UIFont.systemFont(ofSize: 1)
text.flatness = 0.005
let textNode = SCNNode(geometry: text)
let fontScale: Float = 0.01
textNode.scale = SCNVector3(fontScale, fontScale, fontScale)
let (min, max) = (text.boundingBox.min, text.boundingBox.max)
let dx = min.x + 0.5 * (max.x - min.x)
let dy = min.y + 0.5 * (max.y - min.y)
let dz = min.z + 0.5 * (max.z - min.z)
textNode.pivot = SCNMatrix4MakeTranslation(dx, dy, dz)
创建一个PlaneNode并将textNode添加为PlaneNode的childNode:
Create a PlaneNode and add the textNode as a childNode of the PlaneNode:
let width = (max.x - min.x) * fontScale
let height = (max.y - min.y) * fontScale
let plane = SCNPlane(width: CGFloat(width), height: CGFloat(height))
let planeNode = SCNNode(geometry: plane)
planeNode.geometry?.firstMaterial?.diffuse.contents = UIColor.green.withAlphaComponent(0.5)
planeNode.geometry?.firstMaterial?.isDoubleSided = true
planeNode.position = textNode.position
textNode.eulerAngles = planeNode.eulerAngles
planeNode.addChildNode(textNode)
,最后将PlaneNode添加到sceneView:
and at the end add the PlaneNode to sceneView:
sceneView.scene.rootNode.addChildNode(planeNode)
这就是结果:
这篇关于ARKit-如何在另一个SCNNode中包含SCNText(语音气泡)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!