iOS で SceneKit を試す(Swift 3) その30 - ビルトインジオメトリ SCNText(テキスト)
フォントから作成する 3D テキストのジオメトリ。
NSString もしくは NSAttributedString で使用したいテキストを設定する。
ベースラインではなく、ディセンダ(下の空き)を含めるため、
原点においても文字は左下は原点にこないので注意。
また、文字の奥行きが 0 の場合はポリゴンが両面描画される。

Scene Editor でのパラメーター
オブジェクトライブラリの 3D Text を Scene Editor にドラッグ&ドロップして、Attributes Inspector を開く(Command + Option + 4)
1番上の Text の項目で設定値が変更できる

Text
表示する文字列。
Font
フォントとフォントの大きさの設定。
初期値は Helvetica のレギュラーで、サイズは 36 ポイント。
Extrusion depth
3D テキストの奥行き
初期値は 1。
Flatness
3D テキストのカーブなど湾曲している部分のポリゴンの細かさ。
初期値は 0.6。
0 で最も細かくなる。
Chamfer radius
3D テキスト角部分の面取りの大きさ。
初期値は 0 で面取りは行われない。
Chamfer profile
パスから面取りの形を設定する。
Scene Editor からはエッジに丸みが帯びる Round と直線の Straight のみ選択できる
Scene Editor 以外で設定できる項目
| プロパティ名 | 機能 |
|---|---|
| string | 表示する文字列を設定する。NSAttributedString での設定も可能 |
| font | UIFont 設定する |
| containerFrame | CGRect で SCNText の大きさを設定できる |
| isWrapped | 文字の折り返し設定 |
| truncationMode | トランケート設定 |
| alignmentMode | 文字の向き(右寄せ、中央、左寄せ、など) |
| textSize | 文字の大きさ設定。ドキュメントにはこのプロパティが書いてあるが SCNText の定義で見つけることができなかったため使用できるか不明。 |
例: containerFrame による表示領域指定

例: truncationMode によるトランケート指定
領域内に文字が入らないため、「…」でトランケート表示される

注意点
containerFrame で表示サイズを設定しない場合は isWrapped、truncationMode、alignmentMode は使用できない。
NSAttributedString が設定されると font、isWrapped、truncationMode、alignmentMode 設定していても無視される。 なので、自前でアトリビュートを設定する。
chamferProfile は始点が (x: 0.0, y: 1.0)、終点 (x: 1.0, y: 0.0) の間で設定されている UIBezierPath を与えると描画される
chamferRadius、chamferProfile などが正しく設定されていない状態で flatness を 0 にするとクラッシュすることがある。
SCNText のマテリアルは [前面文字、前面 chamfer、伸びている部分、後面 chamfer、後面文字] の5つの配列で構成される。
指定されない場合は、通常どうり firstMaterial が適応される。
例: chamferProfile と マテリアル指定

コード
// シーン設定
let scnView = self.view as! SCNView
scnView.showsStatistics = true
scnView.allowsCameraControl = true
let scene = SCNScene()
scene.background.contents = UIColor.white
scnView.scene = scene
// カメラ設定
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3(2.372,1.473,2.399)
cameraNode.eulerAngles = SCNVector3(-Float.pi * 0.125,Float.pi * 0.25,0)
scene.rootNode.addChildNode(cameraNode)
// ライト設定
let lightNode = SCNNode()
let omniLight = SCNLight()
omniLight.type = .omni
lightNode.light = omniLight
lightNode.position = SCNVector3(0,5,5)
scene.rootNode.addChildNode(lightNode)
// SCNText
let text = SCNText(string: "SCNText!!!", extrusionDepth: 1)
//text.containerFrame = CGRect(x: -0.5, y: -2, width: 2, height: 4)
//text.isWrapped = false
//text.truncationMode = kCATruncationEnd
//text.alignmentMode = kCAAlignmentCenter
//text.font = UIFont(name: "Futura-Bold", size: 0.5)
// NSAttributedString 設定
let style = NSMutableParagraphStyle()
style.lineSpacing = -0.5
let textFont:UIFont = UIFont(name: "Futura-Bold", size: 0.5)!
text.string = NSAttributedString(string: "SCNText!!!", attributes: [
NSParagraphStyleAttributeName: style,
NSFontAttributeName: textFont
])
// その他の設定
text.flatness = 0.0
text.extrusionDepth = 1
text.chamferRadius = 0.02
// chamfer の形状設定
let path = UIBezierPath()
path.move(to: CGPoint(x: 0.0, y: 1.0))
path.addLine(to: CGPoint(x: 0.0, y: 0.75))
path.addLine(to: CGPoint(x: 0.25, y: 0.75))
path.addLine(to: CGPoint(x: 0.25, y: 0.5))
path.addLine(to: CGPoint(x: 0.5, y: 0.5))
path.addLine(to: CGPoint(x: 0.5, y: 0.25))
path.addLine(to: CGPoint(x: 0.75, y: 0.25))
path.addLine(to: CGPoint(x: 0.75, y: 0.0))
path.addLine(to: CGPoint(x: 1.0, y: 0.0))
text.chamferProfile = path
// マテリアル設定
let m1 = SCNMaterial()
let m2 = SCNMaterial()
let m3 = SCNMaterial()
m1.diffuse.contents = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1.0)
m2.diffuse.contents = UIColor.red
m3.diffuse.contents = UIColor.yellow
text.materials = [m3,m2,m1,m2,m3]
let node = SCNNode(geometry: text)
node.position = SCNVector3Zero
scene.rootNode.addChildNode(node)
今回はここまで。