![](/img/trans.png)
[英]RealityKit – Set text programmatically of an Entity of Reality Composer
[英]Dynamically change text of RealityKit entity
我使用 Reality Composer 創建了一個非常簡單的場景(“SpeechScene”),其中單個語音標注 object(“Speech Bubble”)錨定到了人Face
錨。
我已通過以下方式將此場景加載到代碼中:
let speechAnchor = try! Experience.loadSpeechScene()
arView.scene.anchors.append(speechAnchor)
let bubble = (arView.scene as? Experience.SpeechScene)?.speechBubble
它按預期呈現。 但是,我想動態更改這個現有實體的文本。
我在這里發現了一個類似的問題,但我不清楚如何引用 vanilla RealityKit.Entity
object 的meshResource
屬性。
這可能嗎? 謝謝!
首先,您需要找出包含
Bubble Speech
object 的 Reality Composer 場景中的層次結構。 為此,我使用了簡單的 print() 命令:
print(textAnchor.swift!.children[0].components.self) /* Bubble Plate */
print(textAnchor.swift!.children[1].components.self) /* Text Object */
現在我可以提取一個文本實體 object:
let textEntity: Entity = textAnchor.swift!.children[1].children[0].children[0]
和氣泡板實體object:
let bubbleEntity: Entity = textAnchor.swift!.children[0]
這是您可以根據需要進行調整的最終代碼版本:
import RealityKit
class GameViewController: UIViewController {
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
let textAnchor = try! SomeText.loadTextScene()
let textEntity: Entity = textAnchor.swift!.children[1].children[0].children[0]
textAnchor.swift!.parent!.scale = [4,4,4] // Scale for both objects
var textModelComp: ModelComponent = (textEntity.components[ModelComponent])!
var material = SimpleMaterial()
material.baseColor = .color(.red)
textModelComp.materials[0] = material
textModelComp.mesh = .generateText("Obj-C",
extrusionDepth: 0.01,
font: .systemFont(ofSize: 0.08),
containerFrame: CGRect(),
alignment: .left,
lineBreakMode: .byCharWrapping)
textEntity.position = [-0.1,-0.05, 0.01]
textAnchor.swift!.children[1].children[0].children[0].components.set(textModelComp)
arView.scene.anchors.append(textAnchor)
}
}
對於這種情況,您始終可以使用一種更簡單的方法——在 Reality Composer 中創建多個場景,每個場景都必須包含不同speech-object
。
考慮一下,此代碼不是用於跟蹤,它只是使用
Tap Gesture
動態切換兩個對象的測試。 然后,您需要調整此代碼以跟蹤面部。
import RealityKit
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
var counter = 0
var bonjourObject: FaceExperience.Bonjour? = nil
var holaObject: FaceExperience.Hola? = nil
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Reality Composer Scene named "Bonjour"
// Model name – "french"
bonjourObject = try! FaceExperience.loadBonjour()
bonjourObject?.french?.scale = SIMD3(x: 2, y: 2, z: 2)
bonjourObject?.french?.position.y = 0.25
// Reality Composer Scene named "Hola"
// Model name – "spanish"
holaObject = try! FaceExperience.loadHola()
holaObject?.spanish?.scale = SIMD3(x: 2, y: 2, z: 2)
holaObject?.spanish?.position.z = 0.3
}
@IBAction func tapped(_ sender: UITapGestureRecognizer) {
if (counter % 2) == 0 {
arView.scene.anchors.removeAll()
arView.scene.anchors.append(holaObject!)
} else {
arView.scene.anchors.removeAll()
arView.scene.anchors.append(bonjourObject!)
}
counter += 1
}
}
如果您希望文本部分位於同一個位置 - 只需將 object 從一個場景復制粘貼到另一個場景。
@maxxfrazer 的斷言是正確的,即當前動態更改文本的唯一方法是替換Entity
的ModelComponent
,假設它當然遵守HasModel Protocol
。
我寫了一個簡單的擴展,可以幫助解決這個問題:
//-------------------------
//MARK: - Entity Extensions
//-------------------------
extension Entity{
/// Changes The Text Of An Entity
/// - Parameters:
/// - content: String
func setText(_ content: String){ self.components[ModelComponent] = self.generatedModelComponent(text: content) }
/// Generates A Model Component With The Specified Text
/// - Parameter text: String
func generatedModelComponent(text: String) -> ModelComponent{
let modelComponent: ModelComponent = ModelComponent(
mesh: .generateText(text, extrusionDepth: TextElements().extrusionDepth, font: TextElements().font,
containerFrame: .zero, alignment: .center, lineBreakMode: .byTruncatingTail),
materials: [SimpleMaterial(color: TextElements().colour, isMetallic: true)]
)
return modelComponent
}
}
//--------------------
//MARK:- Text Elements
//--------------------
/// The Base Setup Of The MeshResource
struct TextElements{
let initialText = "Cube"
let extrusionDepth: Float = 0.01
let font: MeshResource.Font = MeshResource.Font.systemFont(ofSize: 0.05, weight: .bold)
let colour: UIColor = .white
}
為了使用它,假設您創建了一個名為textEntity
的Entity
:
var textEntity = Entity()
然后,您可以通過簡單地調用以下方法隨時通過替換ModelComponent
和設置MeshResource
來設置動態更改文本:
textEntity.setText("Stack Overflow")
當然,關於居中或對齊文本,您需要做一些簡單的計算(我在這里省略了)。
希望能幫助到你。
找到您的 model 實體(可能通過放置斷點並最初查看子實體),找到符合 HasModel 協議的實體,然后使用 generatetext 將其 model 替換為不同的實體:
https://developer.apple.com/documentation/realitykit/meshresource/3244422-generatetext
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.