首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ARKit -如何在另一个SCNNode中包含SCNText (演讲气泡)

ARKit -如何在另一个SCNNode中包含SCNText (演讲气泡)
EN

Stack Overflow用户
提问于 2018-06-07 09:30:15
回答 2查看 1.7K关注 0票数 3

我试图在ARKit中创建一个带有简单文本的引文生成器。

我可以用文本显示演讲气泡,但文本总是从中间开始,并溢出到演讲气泡之外。

任何帮助使其在演讲气泡的左上角对齐并包裹在演讲气泡内的帮助都将不胜感激。

结果

代码语言:javascript
复制
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))
    }
}

Implementation

代码语言:javascript
复制
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"
}
EN

回答 2

Stack Overflow用户

发布于 2018-08-22 15:39:25

我遇到了同样的问题,最终我解决了它,如下所示:

  • 创建SCNText并将其作为几何图形添加到SCNNode:

让string =“用平面覆盖文本:)”让text = SCNText(string: string,extrusionDepth: 0.1) text.font = UIFont.systemFont(ofSize: 1) text.flatness = 0.005让textNode = SCNNode(geometry: text)让fontScale: Float = 0.01 textNode.scale = SCNVector3(fontScale,fontScale,geometry

让(最小,最大)= (text.boundingBox.min,text.boundingBox.max)让dx = min.x + 0.5 * (max.x - min.x)让dy = min.y + 0.5 * (max.y - min.y)让dz = min.z + 0.5 * (max.z - min.z) textNode.pivot = SCNMatrix4MakeTranslation(dx,dy,dz)

  • 创建一个PlaneNode并将textNode添加为childNode的PlaneNode:

planeNode.addChildNode(textNode)

  • and = (max.x - min.x) * fontScale let height = (max.y - min.y) * fontScale let plane = SCNPlane( width : CGFloat(width),height: CGFloat(height))让PlaneNode = SCNNode(geometry: plane) planeNode.geometry?.firstMaterial?.diffuse.contents = UIColor.green.withAlphaComponent(0.5) planeNode.geometry?.firstMaterial?.isDoubleSided = true UIColor.green.withAlphaComponent= planeNode.position = textNode.position textNode.eulerAngles = planeNode.eulerAngles将planeNode添加到sceneView:

sceneView.scene.rootNode.addChildNode(planeNode)

这就是结果:

票数 5
EN

Stack Overflow用户

发布于 2018-08-16 06:02:54

如果你的文本后面只需要一个白框,我在我的渲染器函数中实现了:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50731775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档