RealityKit – 为什么 ModelEntity 不动态变化?
RealityKit – Why ModelEntity doesn't change dynamically?
我正在构建 AR 应用程序。
这是我的代码
内容视图:
@State var timeAccumulate = 0
let styleCount = 2
let timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect()
var body: some View {
let vc = ARViewContainer(timeAccumulate: timeAccumulate)
.edgesIgnoringSafeArea(.all)
.onAppear(perform: { getData() })
.onReceive(timer) { _ in
timeAccumulate = (timeAccumulate + 1) % styleCount
}
return vc
}
ARViewContainer:
struct ARViewContainer: UIViewRepresentable {
var timeAccumulate: Int
let boxAnchor = try! Experience.loadBox()
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
arView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
arView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
for i in 1...(imageOrder.count+1-1) {
let entity = boxAnchor.findEntity(named: "box\(i)")!
let modelEntity = entity.children[0]
modelEntity.generateCollisionShapes(recursive: true)
arView.installGestures([.all], for: modelEntity as! Entity & HasCollision)
}
arView.scene.anchors.append(boxAnchor)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {
print(timeAccumulate)
for i in 1...(imageOrder.count+1-1) {
let boxThis = boxAnchor.findEntity(named: "box\(i)")!
var modelEntity: ModelEntity!
if timeAccumulate == 0 {
modelEntity = try! ModelEntity.loadModel(named: "Box", in: Bundle.main)
boxThis.children[0] = modelEntity
} else {
modelEntity = try! ModelEntity.loadModel(named: "Chess1", in: Bundle.main)
boxThis.children[0] = modelEntity
}
do {
var material = SimpleMaterial()
let location = documents.appendingPathComponent("\(i).jpg")
let tre = try TextureResource.load(contentsOf: location, withName: "\(i).jpg")
material.baseColor = try MaterialColorParameter.texture(tre)
material.roughness = .float(0.0)
(modelEntity as Entity & HasModel).model?.materials = [material]
}catch{
//print("no image", count)
}
}
}
}
我要25个盒子每十秒变一个模型,盒子,然后是棋子,然后是盒子,然后是棋子
我确定参数 timeAccumulate 正在工作,它是 0,然后是 1,然后是 0,然后是 1。
但观点并没有改变。一直都是盒子
我错过了什么?
谢谢。
您正在做的是将 time Accumulate 设置为 @State 的第一个值。尝试让你 var timeAccumulate: Int
绑定,以便它可以监听你的 @State 变量的变化。
@Binding var timeAccumulate: Int
修复以下错误即可解决问题:
在ContentView
结构中对timeAccumulate
属性包装器使用$
以获得绑定结构。
ARViewContainer(timeAccumulate: $timeAccumulate)
然后在 ARViewContainer
结构中为 timeAccumulate
属性 使用 @Binding
属性。
@Binding var timeAccumulate: Int
baseColor
仍在 iOS 15 中工作,但它与 iOS 16 无关。因此,请改用 color
:
var material = SimpleMaterial()
material.color = .init(tint: .white,
texture: .init(try! .load(named: "texture.png")))
我正在构建 AR 应用程序。 这是我的代码
内容视图:
@State var timeAccumulate = 0
let styleCount = 2
let timer = Timer.publish(every: 10, on: .main, in: .common).autoconnect()
var body: some View {
let vc = ARViewContainer(timeAccumulate: timeAccumulate)
.edgesIgnoringSafeArea(.all)
.onAppear(perform: { getData() })
.onReceive(timer) { _ in
timeAccumulate = (timeAccumulate + 1) % styleCount
}
return vc
}
ARViewContainer:
struct ARViewContainer: UIViewRepresentable {
var timeAccumulate: Int
let boxAnchor = try! Experience.loadBox()
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
arView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
arView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
for i in 1...(imageOrder.count+1-1) {
let entity = boxAnchor.findEntity(named: "box\(i)")!
let modelEntity = entity.children[0]
modelEntity.generateCollisionShapes(recursive: true)
arView.installGestures([.all], for: modelEntity as! Entity & HasCollision)
}
arView.scene.anchors.append(boxAnchor)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {
print(timeAccumulate)
for i in 1...(imageOrder.count+1-1) {
let boxThis = boxAnchor.findEntity(named: "box\(i)")!
var modelEntity: ModelEntity!
if timeAccumulate == 0 {
modelEntity = try! ModelEntity.loadModel(named: "Box", in: Bundle.main)
boxThis.children[0] = modelEntity
} else {
modelEntity = try! ModelEntity.loadModel(named: "Chess1", in: Bundle.main)
boxThis.children[0] = modelEntity
}
do {
var material = SimpleMaterial()
let location = documents.appendingPathComponent("\(i).jpg")
let tre = try TextureResource.load(contentsOf: location, withName: "\(i).jpg")
material.baseColor = try MaterialColorParameter.texture(tre)
material.roughness = .float(0.0)
(modelEntity as Entity & HasModel).model?.materials = [material]
}catch{
//print("no image", count)
}
}
}
}
我要25个盒子每十秒变一个模型,盒子,然后是棋子,然后是盒子,然后是棋子
我确定参数 timeAccumulate 正在工作,它是 0,然后是 1,然后是 0,然后是 1。
但观点并没有改变。一直都是盒子
我错过了什么? 谢谢。
您正在做的是将 time Accumulate 设置为 @State 的第一个值。尝试让你 var timeAccumulate: Int
绑定,以便它可以监听你的 @State 变量的变化。
@Binding var timeAccumulate: Int
修复以下错误即可解决问题:
在
ContentView
结构中对timeAccumulate
属性包装器使用$
以获得绑定结构。ARViewContainer(timeAccumulate: $timeAccumulate)
然后在
ARViewContainer
结构中为timeAccumulate
属性 使用@Binding
属性。@Binding var timeAccumulate: Int
baseColor
仍在 iOS 15 中工作,但它与 iOS 16 无关。因此,请改用color
:var material = SimpleMaterial() material.color = .init(tint: .white, texture: .init(try! .load(named: "texture.png")))