我正在尝试在ARKit中的语音气泡中创建一个带简单文本的引号生成器。
我可以用文字显示语音气泡,但文字总是从中间开始,溢出到讲话泡泡之外。
任何有助于让它在讲话泡泡的左上角对齐并包装在讲话泡泡中的任何帮助都将不胜感激。
结果
类
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"
}
答案 0 :(得分:1)
如果您只需要在文本后面添加一个白框,则可以通过在渲染器功能中完成此操作来实现:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()
............
let testPlane = SCNPlane(width: someWidth, height: someHeight)
let testScene = SKScene(size: CGSize(width: 900, height: 900))
testScene.backgroundColor = UIColor.white
let str = SKLabelNode(text: "This is just a test")
str.color = UIColor.black
str.fontColor = UIColor.black
str.fontSize = 45.5
str.position = CGPoint(x: stuff.size.width / 2,
y: stuff.size.height / 2)
testScene.addChild(str)
testPlane.firstMaterial?.diffuse.contents = testScene
testPlane.firstMaterial?.isDoubleSided = true
testPlane.firstMaterial?.diffuse.contentsTransform = SCNMatrix4Translate(SCNMatrix4MakeScale(1, -1, 1), 0, 1, 0)
let testNode = SCNNode(geometry: testPlane)
testNode.eulerAngles.x = -.pi / 2
testNode.position = SCNVector3Make(0.0,0.0,0.0)
node.addChildNode(testNode)
}
答案 1 :(得分:1)
我遇到了同样的问题,终于解决了以下问题:
创建一个SCNText并将其作为几何体添加到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)
Coordinate the text pivot form left bottom to center:
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:
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:
sceneView.scene.rootNode.addChildNode(planeNode)
这就是结果: